-
Notifications
You must be signed in to change notification settings - Fork 6.1k
OAuth2AccessTokenResponse should allow to customize behavior in absence of "expires_in" parameter #8701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for your answer @jgrandja // For the AC flow
.oauth2Login()
.loginPage("/oauth2/authorization/gitlab")
.tokenEndpoint(c -> c.accessTokenResponseClient(authCodeCustomGitLabExpiresInAccessTokenResponseClientFor())); Then assuming #8700 is fixed I would need to configure the @Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.refreshToken(configurer -> configurer.accessTokenResponseClient(refreshCustomGitLabExpiresInAccessTokenResponseClient()))
.clientCredentials()
.password()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
} And finally I need all this boilerplate @Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authCodeCustomGitLabExpiresInAccessTokenResponseClientFor() {
DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient =
new DefaultAuthorizationCodeTokenResponseClient();
accessTokenResponseClient.setRestOperations(customGitLabExpiresInRestTemplate());
return accessTokenResponseClient;
}
@Bean
public OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> refreshCustomGitLabExpiresInAccessTokenResponseClient() {
DefaultRefreshTokenTokenResponseClient refreshTokenTokenResponseClient =
new DefaultRefreshTokenTokenResponseClient();
refreshTokenTokenResponseClient.setRestOperations(customGitLabExpiresInRestTemplate());
return refreshTokenTokenResponseClient;
}
private static RestTemplate customGitLabExpiresInRestTemplate() {
OAuth2AccessTokenResponseHttpMessageConverter tokenResponseHttpMessageConverter =
new OAuth2AccessTokenResponseHttpMessageConverter();
tokenResponseHttpMessageConverter.setTokenResponseConverter(customGitLabExpiresInTokenResponseConverter());
RestTemplate restTemplate = new RestTemplate(Arrays.asList(
new FormHttpMessageConverter(), tokenResponseHttpMessageConverter));
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
return restTemplate;
}
private static Converter<Map<String, String>, OAuth2AccessTokenResponse> customGitLabExpiresInTokenResponseConverter() {
MapOAuth2AccessTokenResponseConverter mapOAuth2AccessTokenResponseConverter = new MapOAuth2AccessTokenResponseConverter();
return tokenResponseParameters -> {
OAuth2AccessTokenResponse original = mapOAuth2AccessTokenResponseConverter.convert(tokenResponseParameters);
String expiresIn = tokenResponseParameters.get(OAuth2ParameterNames.EXPIRES_IN);
if (expiresIn != null) {
return original;
}
OAuth2AccessToken accessToken = original.getAccessToken();
return OAuth2AccessTokenResponse.withToken(accessToken.getTokenValue())
.tokenType(accessToken.getTokenType())
.scopes(accessToken.getScopes())
.expiresIn(Duration.ofDays(1).toSeconds())
.refreshToken(original.getRefreshToken().getTokenValue())
.additionalParameters(original.getAdditionalParameters())
.build();
};
} Maybe my conf is not optimal but it took me a hard time to get this right (at least I hope it is), even if all the individual pieces are described in the documentation. |
It is a rare case. Most providers I've seen thus far provide the I reviewed your config and this is exactly how you would go about customizing the token response. Looks good to me. |
@jgrandja Thank you for your feedback |
I know this is a pretty old thread, but recently came across this issue due to Salesforce API not providing the @Bean
OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository registrationRepository, OAuth2AuthorizedClientService clientService, SalesforceClientCredentialsTokenResponseClient tokenResponseClient) {
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials(configurer -> configurer.accessTokenResponseClient(tokenResponseClient))
.build();
AuthorizedClientServiceOAuth2AuthorizedClientManager manager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(registrationRepository, clientService);
manager.setAuthorizedClientProvider(authorizedClientProvider);
return manager;
} @Component
public class SalesforceClientCredentialsTokenResponseClient implements OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> {
private final DefaultClientCredentialsTokenResponseClient delegate = new DefaultClientCredentialsTokenResponseClient();
@Override
public OAuth2AccessTokenResponse getTokenResponse(OAuth2ClientCredentialsGrantRequest authorizationGrantRequest) {
OAuth2AccessTokenResponse response = delegate.getTokenResponse(authorizationGrantRequest);
return OAuth2AccessTokenResponse.withResponse(response)
.expiresIn(Duration.ofHours(2).toSeconds()) // or whatever your session duration should be
.build();
}
} |
Expected Behavior
From the spec quoted by
OAuth2AccessTokenResponse
(https://tools.ietf.org/html/rfc6749#section-5.1) the default value could differ depending on the AS.It would be nice if it was possible to describe the default value (or
"expires_in":null
) meaning through the config.Current Behavior
OAuth2AccessTokenResponse assumes that if there is no
expires_in
or"expires_in":null
the token will expire one second later.Context
I'm using Gitlab as an OIDC provider.
Gitlab does not specify an expiration for access token (https://gitlab.com/gitlab-org/gitlab/-/issues/21745), and return
in the token response.
The access token is then always refreshed, while the access token is still valid.
The text was updated successfully, but these errors were encountered: