0

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());
Espresso
  • 5,378
  • 4
  • 35
  • 66

1 Answers1

1

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();
    }
}
Indra Basak
  • 7,124
  • 1
  • 26
  • 45
  • Thanks for the quick example. That's the cleanest way for this crosscutting aspect. I was trying to channel two different pointcuts() into oneAdvice() [one from a .ws package and another from a .rest package]. Will check ways to do that. – Espresso Oct 30 '17 at 23:01