Search code examples
javaspring-bootspring-security

How do I get a JwtAuthenticationToken for my HandlerMethodArgumentResolver from the request's Authorization header?


I have a Spring Boot application that requires a JwtAuthenticationToken passed in a HTTP Authorization header. The header itself provides a bearer token; Spring is doing some magic that I am currently unaware of to convert that bearer token string into a JwtAuthenticationToken. I have some code that extracts the user id from the token, which is used to locate the correct resources on the server.

private String getUidFromToken(JwtAuthenticationToken token) {
  // this is placeholder code to demonstrate what I'm doing with the token
}

public ResponseEntity<String> getUserProfile(JwtAuthenticationToken token) {
  String uid = getUidFromToken(token);
  // rest of the code
}

Since I require these tokens in a couple of different places, I decided to look into moving the getUidFromToken code into a HandlerMethodArgumentResolver. The trouble I'm having is that I need a JwtAuthenticationToken, but I only get the bearer token from the Authorization header as a string.

Is it possible for me to get that JwtAuthenticationToken instead of a string?


Solution

  • I figured it out with some help from a professional acquaintance. The trick was to grab the static security context which allows you to get ahold of the current authentication. Then, getting the uid claim I was looking for was trivial.

    I used a Baeldung article to help me scaffold the HandlerMethodArgumentResolver: https://www.baeldung.com/spring-mvc-custom-data-binder#1-custom-argument-resolver

    And here is what I did in the resolveArgument method:

    @Override
    public Object resolveArgument(
        MethodParameter parameter,
        ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest,
        WebDataBinderFactory binderFactory)
        throws Exception {
      final var auth = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
      final var token = auth.getToken();
      if (token.hasClaim("uid")) {
        return token.getClaimAsString("uid");
      } else {
        return null;
      }
    }