My application needs to be an API client, using Spring Security, Oauth 2.0, and OpenID, in Spring Boot. My issuer URI for OpenID should not have a trailing "/", the API provider mentioned that in the documentation.
application.yaml
spring:
security:
oauth2:
client:
registration:
IdOfMyApp:
provider: https://api.provider.guys.com
client-id: [my id here]
client-secret: [my secret here]
client-authentication-method: basic
authorization-grant-type: authorization_code
scope:
- pr.pro
- pr.act
- openid
- offline
redirect-uri: https://my.domain.com/fallback
client-name: My App Name
provider:
IdOfProvider:
authorization-uri: https://api.provider.guys.com/oauth2/auth
token-uri: https://api.provider.guys.com/oauth2/token
issuer-uri: https://api.provider.guys.com
resourceserver:
jwt:
issuer-uri: https://api.provider.guys.com
logging:
level:
'[org.springframework.web]': DEBUG
so my issuer-uri is https://api.provider.guys.com (I made it up to be a placeholder for example, but real URI is similar).
When I go to the ClientRegistration.Builder withProviderConfiguration(AuthorizationServerMetadata metadata, String issuer) method in org.springframework.security.oauth2.client.registration in debug mode, I've noticed that the metadata parameter has "https://api.provider.guys.com/" (with trailing /) and the issuer parameter has a value of "https://api.provider.guys.com".
private static ClientRegistration.Builder withProviderConfiguration(AuthorizationServerMetadata metadata,
String issuer) {
String metadataIssuer = metadata.getIssuer().getValue();
Assert.state(issuer.equals(metadataIssuer),
() -> "The Issuer \"" + metadataIssuer + "\" provided in the configuration metadata did "
+ "not match the requested issuer \"" + issuer + "\"");
String name = URI.create(issuer).getHost();
ClientAuthenticationMethod method = getClientAuthenticationMethod(metadata.getTokenEndpointAuthMethods());
Map<String, Object> configurationMetadata = new LinkedHashMap<>(metadata.toJSONObject());
// @formatter:off
return ClientRegistration.withRegistrationId(name)
.userNameAttributeName(IdTokenClaimNames.SUB)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.clientAuthenticationMethod(method)
.redirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}")
.authorizationUri((metadata.getAuthorizationEndpointURI() != null) ? metadata.getAuthorizationEndpointURI().toASCIIString() : null)
.providerConfigurationMetadata(configurationMetadata)
.tokenUri(metadata.getTokenEndpointURI().toASCIIString())
.issuerUri(issuer)
.clientName(issuer);
// @formatter:on
}
Then this exception occurs:
Caused by: java.lang.IllegalStateException: The Issuer "https://api.provider.guys.com/" provided in the configuration metadata did not match the requested issuer "https://api.provider.guys.com"
My OAuthClientConfiguration class
@Configuration
public class OAuthClientConfiguration
{
@Bean
ReactiveClientRegistrationRepository clientRegistrations(
@Value(value = "${spring.security.oauth2.client.provider.IdOfProvider.token-uri}") String tokenUri,
@Value(value = "${spring.security.oauth2.client.registration.IdOfMyApp.client-id}") String clientId,
@Value(value = "${spring.security.oauth2.client.registration.IdOfMyApp.client-secret}") String clientSecret,
@Value(value = "${spring.security.oauth2.client.registration.IdOfMyApp.authorization-grant-type}") String authorizationGrantType,
@Value(value = "${spring.security.oauth2.client.registration.IdOfMyApp.redirect-uri}") String redirectUri,
@Value(value = "${spring.security.oauth2.client.provider.IdOfProvider.authorization-uri}") String authorizationUri,
@Value(value = "${spring.security.oauth2.client.provider.IdOfProvider.issuer-uri}") String issuerUri)
{
ClientRegistration registration = ClientRegistration
.withRegistrationId("IdOfMyApp")
.tokenUri(tokenUri)
.clientId(clientId)
.clientSecret(clientSecret)
.scope("pr.pro", "pr.act", "openid", "offline")
.authorizationGrantType(new AuthorizationGrantType(authorizationGrantType))
.redirectUri(redirectUri)
.authorizationUri(authorizationUri)
.issuerUri(issuerUri)
.build();
return new InMemoryReactiveClientRegistrationRepository(registration);
}
@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations)
{
InMemoryReactiveOAuth2AuthorizedClientService clientService = new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrations);
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrations, clientService);
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth.setDefaultClientRegistrationId("IdOfMyApp");
return WebClient.builder().filter(oauth).build();
}
}
How to prevent that "/" from appending to my issuer URI in AuthorizationServerMetadata object?