Search code examples
spring-dataspring-aopspring-aspects

How to print some logs "before" a spring-data repository method, without custom repo


I have a Spring data repository. When http://localhost:8080/persons webservice is called, I want to log something. I DO NOT want to make MyCustomRepository<>. Cleaner options?

Repo class:

@RepositoryRestResource(collectionResourceRel = "persons", path = "persons")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {

    List<Person> findByLastName(@Param("name") String name);

Sample log:

log.error("AccessToken: " + securityContext.getTokenString());
log.error("User: {} / {}", accessToken.getPreferredUsername(), accessToken.getName());
log.error("Principal: {}", principal.getName());

Solution

  • You can create an aspect to intercept calls to your PersonRepository. From there you can access OAuth2 access token and the security context to retrieve the principal. Here is an example,

    @Component
    @Aspect
    @Log
    public class SecurityAspect {
    
        @Autowired
        private OAuth2ClientContext oauth2ClientContext;
    
        @Pointcut("execution(public * my.example.repository.PersonRepository.*(..))")
        public void pointcut() {
        }
    
        @Around("pointcut()")
        public Object advice(ProceedingJoinPoint pjp) throws Throwable {
            log.info(
                    "Entering SecurityAspect.advice() in class "
                            + pjp.getSignature().getDeclaringTypeName()
                            + " - method: " + pjp.getSignature().getName());
    
            OAuth2AccessToken accessToken = oauth2ClientContext.getAccessToken();
            log.info("AccessToken: " + accessToken);
    
            if (SecurityContextHolder.getContext().getAuthentication()
                    instanceof OAuth2Authentication) {
                OAuth2Authentication authentication =
                        (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
                if (authentication.getUserAuthentication() instanceof UsernamePasswordAuthenticationToken) {
                    UsernamePasswordAuthenticationToken userToken =
                            (UsernamePasswordAuthenticationToken) authentication.getUserAuthentication();
                    log.info("Principal id: " + userToken.getPrincipal());
                    if (userToken.getDetails() instanceof Map) {
                        Map details = (Map) userToken.getDetails();
                        log.info("Principal Name: " + details.get("name"));
                    }
                }
            }
    
            return pjp.proceed();
        }
    }