Skip to content
Advertisement

Spring Security injecting null @AuthenticatedPrincipal into controllers

Java 11, Spring Security here. I have the following endpoint/method in my @RestController:

@GetMapping("/centerPoint")
public void centerPoint(@AuthenticationPrincipal ExpiringUsernameAuthenticationToken token,
          HttpServletResponse response) throws IOException {
            
  Authentication auth = SecurityContextHolder.getContext().getAuthentication();
  if (auth == null) {
    LOGGER.warn("Current authentication instance from security context is null");
    response.sendRedirect("some redirect url");
    return;
  }

  SAMLCredential attributes = ((SAMLCredential) token.getCredentials());
  // ...rest of code omitted for brevity
  
}

When I set a breakpoint inside this method and login to my app, token is null (meaning it was not properly injected as an @AuthenticatedPrincipal) however SecurityContextHolder.getContext().getAuthentication() returns an Authentication instance that looks totally fine. I get a NPE when the token.getCredentials() gets called at the bottom there.

I know this is an incomplete code snippet and I’m happy to provide other parts of the security code (WebSecurityConfig, etc.) however I’m wonder: what would cause SecurityContextHolder.getContext().getAuthentication() to be non-null, but not have a token to inject?

Advertisement

Answer

The javadoc in AuthenticationPrincipalArgumentResolver says the following:

Will resolve the CustomUser argument using Authentication.getPrincipal() from the SecurityContextHolder. If the Authentication or Authentication.getPrincipal() is null, it will return null. If the types do not match, null will be returned unless AuthenticationPrincipal.errorOnInvalidType() is true in which case a ClassCastException will be thrown.

So you should make sure that the Authentication.getPrincipal() type is ExpiringUsernameAuthenticationToken.

Debug your application and see which type returns from SecurityContextHolder.getContext().getAuthentication() and from authentication.getPrincipal()

Advertisement