I'm trying to setup Spring Boot 3 to use both authentication using JWT and HTTP sessions with X-Auth tokens. The goal is to use X-Auth tokens as primary authentication method, but users might authenticate using an external provider which grants a JWT access token.
I've successfully managed to create two different authorization endpoints, one at /auth using form based login and returns an X-Auth token, and one at /authJwt. JWT authorization is only enabled at /authJwt and all other endpoints are protected using X-Auth tokens.
Is it possible to enable generation of X-Auth tokens by authentication using a JWT? I've configured HTTP sessions to always be created, and a call to /authJwt returns an X-Auth token in the HTTP header. But the X-Auth token is not valid when trying to authenticate.
This is the security configuration which I'm using (I've removed some irrelevant parts):
@Configuration
@EnableWebSecurity()
public class WebSecurityConfiguration {
// Endpoints which will be public and not require authentication
private static final String[] AUTH_WHITELIST = {
"/auth"
};
/**
* Filter chain for authenticating using JWT tokens
*/
@Bean
@Order(1)
public SecurityFilterChain oAuth2ResourceFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.securityMatcher("/authJwt")
.cors().and().csrf().disable()
.requestCache().disable().exceptionHandling().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.authorizeHttpRequests().anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return httpSecurity.build();
}
/**
* Filter chain for enabling authentication.
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors().and().csrf().disable()
.requestCache().disable().exceptionHandling().and()
.formLogin().loginPage("/auth").usernameParameter("loginName").passwordParameter("loginPassword")
.successHandler((request, response, authentication) -> response.setStatus(HttpServletResponse.SC_OK))
.and()
.authorizeHttpRequests(requests -> requests
.requestMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().authenticated()
)
// Return 401 on no session
.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
.and()
.logout();
return httpSecurity.build();
}
}
This is the configuration for the sessions:
@Configuration()
@EnableSpringHttpSession
public class SpringHttpSessionConfig {
@Bean
public MapSessionRepository sessionRepository() {
return new MapSessionRepository(new ConcurrentHashMap<>());
}
@Bean
public HttpSessionIdResolver httpSessionIdResolver() {
return HeaderHttpSessionIdResolver.xAuthToken();
}
}
Can anyone point in the correct direction of exchanging JWT tokens for X-Auth tokens?
I realized I had assumed I needed to use Spring Session, but it was easier to solve it without sessions. Instead I added a custom token store and token filters which manages authorization. The token store:
Token filter which is added to the
SecurityFilterChainto validate access tokens:The tokens are genereated either on the success handler of the form login:
Or in the endpoint for the
/authJwtendpoint: