⬅️ Back to Infrastructure Index
Security Layer
The Security Layer handles OAuth2 authentication, authorization checks, and access control. It manages user authentication from third-party providers and enforces permission rules.
OAuth2 Authentication
Handles third-party authentication (Google, GitHub, etc.):
@Component
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
private final AppUserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) {
OAuth2User oauth2User = super.loadUser(userRequest);
String email = oauth2User.getAttribute("email");
String name = oauth2User.getAttribute("name");
String oauth2Id = oauth2User.getName();
AppUser user = userRepository.findByEmail(email)
.orElseGet(() -> createNewUser(email, name, oauth2Id));
user.setLastLogin(LocalDateTime.now());
userRepository.save(user);
return oauth2UserWrapper(user, oauth2User);
}
private AppUser createNewUser(String email, String name, String oauth2Id) {
return AppUser.builder()
.id(UUID.randomUUID().toString())
.email(email)
.name(name)
.oauth2Id(oauth2Id)
.role(Role.USER)
.createdAt(LocalDateTime.now())
.build();
}
}Authorization with @PreAuthorize
Method-level authorization checks:
@Service
public class SupplierServiceImpl {
@PreAuthorize("isAuthenticated()")
public List<SupplierDTO> findAll() {
return repository.findAll().stream()
.map(mapper::toDTO)
.toList();
}
@PreAuthorize("hasRole('ADMIN')")
public SupplierDTO create(CreateSupplierDTO dto) {
return mapper.toDTO(repository.save(mapper.toEntity(dto)));
}
}Get Current User
Access authenticated user from SecurityContext:
@Service
public class SupplierServiceImpl {
private String getCurrentUsername() {
Authentication auth = SecurityContextHolder
.getContext().getAuthentication();
return auth != null ? auth.getName() : "SYSTEM";
}
@Transactional
public SupplierDTO create(CreateSupplierDTO dto) {
Supplier entity = mapper.toEntity(dto);
entity.setCreatedBy(getCurrentUsername());
return mapper.toDTO(repository.save(entity));
}
}