Spring Boot Security – Use token from Cookies if Authorization header missing

I currently authenticate my requests against the JWK of my authorization server. I’m using the spring-boot-starter-oauth2-resource-server package on spring-boot 2.3. The JWT is taken out from the Authorization: Bearer <token> header and validated against the JWK endpoint. My security config looks like this:

SecurityConfig.java

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  protected Environment env;

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http.authorizeRequests().antMatchers("/logs").permitAll();
    http.authorizeRequests().antMatchers("/", "/api/**").authenticated();
    http.oauth2ResourceServer().jwt();
  }
}

application.properties

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://auth.work.com/v1/jwk

External users don’t have the Authorization: ... header in their requests, but instead have the following 2 cookies that make up the JWT:

auth.token_type = Bearer
auth.access_token = <token>

Is there a way to extract the JWT from the cookies and validate against the auth server if the the Authorization: ... header is missing? Could I extract the cookies and add a header to the request before it tries to authorize? Or it could even be a second method in the authentication chain.

Answer

I found out about custom token resolvers and ended up creating one to validate both the header and the cookie. I’m not sure if this is the cleanest solution, but it works.

The only issue I have with this is that it doesn’t automatically validate the Authorization: Bearer ... header anymore, so I had to add the code for it too.

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
    http.authorizeRequests().antMatchers("/logs").permitAll();
    http.authorizeRequests().antMatchers("/", "/api/**").authenticated();
    http.oauth2ResourceServer().jwt().and().bearerTokenResolver(this::tokenExtractor);
  }

  public String tokenExtractor(HttpServletRequest request) {
    String header = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (header != null)
      return header.replace("Bearer ", "");
    Cookie cookie = WebUtils.getCookie(request, "auth.access_token");
    if (cookie != null)
      return cookie.getValue();
    return null;
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *