I have a requirement in my system that in some flows I have to use a JWT with a specific private/public key and other flows have to user another JWT with other keys.
I'm using spring oauth2 authorization server 1.0.0.
When I try to set two keys, it works okay to generate the jwks endpoint, but when I do the POST /oauth2/token I got the following exception:
org.springframework.security.oauth2.jwt.JwtEncodingException: An error occurred while attempting to encode the Jwt: Found multiple JWK signing keys for algorithm 'RS256'
at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.selectJwk(NimbusJwtEncoder.java:128) ~[spring-security-oauth2-jose-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.jwt.NimbusJwtEncoder.encode(NimbusJwtEncoder.java:108) ~[spring-security-oauth2-jose-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.server.authorization.token.JwtGenerator.generate(JwtGenerator.java:159) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.oauth2.server.authorization.token.JwtGenerator.generate(JwtGenerator.java:58) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.oauth2.server.authorization.token.DelegatingOAuth2TokenGenerator.generate(DelegatingOAuth2TokenGenerator.java:59) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationProvider.authenticate(OAuth2ClientCredentialsAuthenticationProvider.java:125) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter.doFilterInternal(OAuth2TokenEndpointFilter.java:167) ~[spring-security-oauth2-authorization-server-1.0.0.jar:1.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
Is that okay my concept of having to JWK keys in the same authorization server?
How can I implement the authorization server to use in a specific client credentials request one JWK key, and in another client credential request another JWK key?
My code:
@EnableWebSecurity
@Configuration
@Slf4j
public class AuthSecurityConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
return http.formLogin(Customizer.withDefaults()).build();
}
@Bean
public SecurityFilterChain authFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
return http.formLogin(Customizer.withDefaults()).build();
}
public RegisteredClientRepository registeredClientRepository(PasswordEncoder passwordEncoder
,JdbcTemplate jdbcTemplate
) {
JdbcRegisteredClientRepository clientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
return clientRepository;
}
@Bean
public OAuth2AuthorizationService auth2AuthorizationService(JdbcOperations jdbcOperations,
RegisteredClientRepository registeredClientRepository) {
return new JdbcOAuth2AuthorizationService(
jdbcOperations,
registeredClientRepository
);
}
@Bean
public OAuth2AuthorizationConsentService oAuth2AuthorizationConsentService(JdbcOperations jdbcOperations,
RegisteredClientRepository registeredClientRepository) {
return new JdbcOAuth2AuthorizationConsentService(
jdbcOperations,
registeredClientRepository
);
}
@Bean
public JWKSet jwkSet(AuthProperties authProperties) throws Exception {
List<JWK> keys = new ArrayList<>();
for (JksProperties jwk : authProperties.getJksList()) {
keys.add(loadRsa(jwk));
}
return new JWKSet(keys);
}
@Bean
public JWKSource<SecurityContext> jwkSource(JWKSet jwkSet) {
return ((jwkSelector, securityContext) -> jwkSelector.select(jwkSet));
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().build();
}