Describe the bug
OAuth2AuthorizationCodeAuthenticationProvider does not respect the generated OAuth2AccessToken.TokenType and set it always to Bearer.
The internal class method OAuth2AuthenticationProviderUtils.accessToken.accessToken used by OAuth2AuthorizationCodeAuthenticationProvider do not respect the TokenType generated by the OAuth2TokenGenerator even if this is creating an OAuth2AccessToken that contains a TokenType
Access token token_type field should be able to store custom values per spec:
To Reproduce
Create a custom generator that returns an OAuth2AccessToken with a custom TokenType
public class CustomGenerator implements OAuth2TokenGenerator<OAuth2AccessToken> {
public CustomGenerator() {
}
@Override
public OAuth2AccessToken generate(OAuth2TokenContext context) {
if (!OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) {
return null;
}
OAuth2AccessToken.TokenType tokenType = new OAuth2AccessToken.TokenType("custom-type");
String tokenValue = "TEST"
Instant issuedAt = Instant.now();
Instant expiresAt = issuedAt.plus(1, HOUR);
// Return JWT as OAuth2AccessToken with configured token type
return new OAuth2AccessToken(
tokenType,
tokenValue,
issuedAt,
expiresAt
);
}
}
Setup the authorization server filter chain with the custom token generator
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(
HttpSecurity http,
) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
var tokenGenerator = new CustomGenerator();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenGenerator(tokenGenerator) // Configure custom token generator
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
);
return http.build();
}
Define the default security chain with login
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
// Form login handles the redirect to the login page from the
// authorization server filter chain
.formLogin(Customizer.withDefaults());
return http.build();
}
Expected behavior
The token sent to the caller and saved to the OAuth2AuthorizationService contains the custom TokenType
Sample
Describe the bug
OAuth2AuthorizationCodeAuthenticationProviderdoes not respect the generatedOAuth2AccessToken.TokenTypeand set it always toBearer.The internal class method
OAuth2AuthenticationProviderUtils.accessToken.accessTokenused byOAuth2AuthorizationCodeAuthenticationProviderdo not respect theTokenTypegenerated by theOAuth2TokenGeneratoreven if this is creating anOAuth2AccessTokenthat contains aTokenTypeAccess token
token_typefield should be able to store custom values per spec:To Reproduce
Create a custom generator that returns an
OAuth2AccessTokenwith a customTokenTypeSetup the authorization server filter chain with the custom token generator
Define the default security chain with login
Expected behavior
The token sent to the caller and saved to the
OAuth2AuthorizationServicecontains the customTokenTypeSample