Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public Builder getBuilder(String registrationId) {
builder.tokenUri("https://www.googleapis.com/oauth2/v4/token");
builder.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs");
builder.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
builder.issuerUri("https://accounts.google.com");
builder.userNameAttributeName(IdTokenClaimNames.SUB);
builder.clientName("Google");
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ public void parseWhenIssuerUriConfiguredThenRequestConfigFromIssuer() throws Exc
.isEqualTo(AuthenticationMethod.HEADER);
assertThat(googleProviderDetails.getUserInfoEndpoint().getUserNameAttributeName()).isEqualTo("sub");
assertThat(googleProviderDetails.getJwkSetUri()).isEqualTo("https://example.com/oauth2/v3/certs");
assertThat(googleProviderDetails.getIssuerUri()).isEqualTo(serverUrl);
}

@Test
Expand Down Expand Up @@ -195,6 +196,7 @@ public void parseWhenMultipleClientsConfiguredThenAvailableInRepository() {
.isEqualTo(AuthenticationMethod.HEADER);
assertThat(googleProviderDetails.getUserInfoEndpoint().getUserNameAttributeName()).isEqualTo("sub");
assertThat(googleProviderDetails.getJwkSetUri()).isEqualTo("https://www.googleapis.com/oauth2/v3/certs");
assertThat(googleProviderDetails.getIssuerUri()).isEqualTo("https://accounts.google.com");

ClientRegistration githubRegistration = clientRegistrationRepository.findByRegistrationId("github-login");
assertThat(githubRegistration).isNotNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,11 @@ The following table outlines the mapping of the Spring Boot 2.x OAuth Client pro
|`spring.security.oauth2.client.provider._[providerId]_.user-info-authentication-method`
|`providerDetails.userInfoEndpoint.authenticationMethod`


|`spring.security.oauth2.client.provider._[providerId]_.user-name-attribute`
|`providerDetails.userInfoEndpoint.userNameAttributeName`

|`spring.security.oauth2.client.provider._[providerId]_.issuer-uri`
|`providerDetails.issuerUri`
|===

[TIP]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ public OAuth2TokenValidatorResult validate(Jwt idToken) {

// 2. The Issuer Identifier for the OpenID Provider (which is typically obtained during Discovery)
// MUST exactly match the value of the iss (issuer) Claim.
String metadataIssuer = (String) this.clientRegistration.getProviderDetails().getConfigurationMetadata()
.get("issuer");
String metadataIssuer = this.clientRegistration.getProviderDetails().getIssuerUri();

if (metadataIssuer != null && !Objects.equals(metadataIssuer, idToken.getIssuer().toExternalForm())) {
invalidClaims.put(IdTokenClaimNames.ISS, idToken.getIssuer());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ public class ProviderDetails implements Serializable {
private String tokenUri;
private UserInfoEndpoint userInfoEndpoint = new UserInfoEndpoint();
private String jwkSetUri;
private String issuerUri;
private Map<String, Object> configurationMetadata = Collections.emptyMap();

private ProviderDetails() {
Expand Down Expand Up @@ -204,6 +205,16 @@ public String getJwkSetUri() {
return this.jwkSetUri;
}

/**
* Returns the uri for the OpenID Provider Issuer.
*
* @since 5.4
* @return the uri for the OpenID Provider Issuer
*/
public String getIssuerUri() {
return this.issuerUri;
}

/**
* Returns a {@code Map} of the metadata describing the provider's configuration.
*
Expand Down Expand Up @@ -296,6 +307,7 @@ public static class Builder implements Serializable {
private AuthenticationMethod userInfoAuthenticationMethod = AuthenticationMethod.HEADER;
private String userNameAttributeName;
private String jwkSetUri;
private String issuerUri;
private Map<String, Object> configurationMetadata = Collections.emptyMap();
private String clientName;

Expand All @@ -317,6 +329,7 @@ private Builder(ClientRegistration clientRegistration) {
this.userInfoAuthenticationMethod = clientRegistration.providerDetails.userInfoEndpoint.authenticationMethod;
this.userNameAttributeName = clientRegistration.providerDetails.userInfoEndpoint.userNameAttributeName;
this.jwkSetUri = clientRegistration.providerDetails.jwkSetUri;
this.issuerUri = clientRegistration.providerDetails.issuerUri;
Map<String, Object> configurationMetadata = clientRegistration.providerDetails.configurationMetadata;
if (configurationMetadata != EMPTY_MAP) {
this.configurationMetadata = new HashMap<>(configurationMetadata);
Expand Down Expand Up @@ -486,6 +499,17 @@ public Builder jwkSetUri(String jwkSetUri) {
return this;
}

/**
* Sets the uri for the OpenID Provider Issuer.
*
* @param issuerUri the uri for the OpenID Provider Issuer
* @return the {@link Builder}
*/
public Builder issuerUri(String issuerUri) {
this.issuerUri = issuerUri;
return this;
}

/**
* Sets the metadata describing the provider's configuration.
*
Expand Down Expand Up @@ -554,6 +578,7 @@ private ClientRegistration create() {
providerDetails.userInfoEndpoint.authenticationMethod = this.userInfoAuthenticationMethod;
providerDetails.userInfoEndpoint.userNameAttributeName = this.userNameAttributeName;
providerDetails.jwkSetUri = this.jwkSetUri;
providerDetails.issuerUri = this.issuerUri;
providerDetails.configurationMetadata = Collections.unmodifiableMap(this.configurationMetadata);
clientRegistration.providerDetails = providerDetails;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ private static ClientRegistration.Builder withProviderConfiguration(Authorizatio
.authorizationUri(metadata.getAuthorizationEndpointURI().toASCIIString())
.providerConfigurationMetadata(configurationMetadata)
.tokenUri(metadata.getTokenEndpointURI().toASCIIString())
.issuerUri(issuer)
.clientName(issuer);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ public void deserializeWhenMixinRegisteredThenDeserializes() throws Exception {
.isEqualTo(expectedClientRegistration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName());
assertThat(clientRegistration.getProviderDetails().getJwkSetUri())
.isEqualTo(expectedClientRegistration.getProviderDetails().getJwkSetUri());
assertThat(clientRegistration.getProviderDetails().getIssuerUri())
.isEqualTo(expectedClientRegistration.getProviderDetails().getIssuerUri());
assertThat(clientRegistration.getProviderDetails().getConfigurationMetadata())
.containsExactlyEntriesOf(clientRegistration.getProviderDetails().getConfigurationMetadata());
assertThat(clientRegistration.getClientName())
Expand Down Expand Up @@ -203,6 +205,7 @@ public void deserializeWhenRequiredAttributesOnlyThenDeserializes() throws Excep
.isEqualTo(expectedClientRegistration.getProviderDetails().getUserInfoEndpoint().getAuthenticationMethod());
assertThat(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName()).isNull();
assertThat(clientRegistration.getProviderDetails().getJwkSetUri()).isNull();
assertThat(clientRegistration.getProviderDetails().getIssuerUri()).isNull();
assertThat(clientRegistration.getProviderDetails().getConfigurationMetadata()).isEmpty();
assertThat(clientRegistration.getClientName())
.isEqualTo(clientRegistration.getRegistrationId());
Expand Down Expand Up @@ -276,6 +279,7 @@ private static String asJson(ClientRegistration clientRegistration) {
" \"userNameAttributeName\": " + (userInfoEndpoint.getUserNameAttributeName() != null ? "\"" + userInfoEndpoint.getUserNameAttributeName() + "\"" : null) + "\n" +
" },\n" +
" \"jwkSetUri\": " + (providerDetails.getJwkSetUri() != null ? "\"" + providerDetails.getJwkSetUri() + "\"" : null) + ",\n" +
" \"issuerUri\": " + (providerDetails.getIssuerUri() != null ? "\"" + providerDetails.getIssuerUri() + "\"" : null) + ",\n" +
" \"configurationMetadata\": {\n" +
" " + configurationMetadata + "\n" +
" }\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@ public void validateWhenMetadataIssuerMismatchThenHasErrors() {
* When the issuer is set in the provider metadata, and it does not match the issuer in the ID Token,
* the validation must fail
*/
Map<String, Object> configurationMetadata = new HashMap<>();
configurationMetadata.put("issuer", "https://issuer.somethingelse.com");
this.registration = this.registration.providerConfigurationMetadata(configurationMetadata);
this.registration = this.registration.issuerUri("https://issuer.somethingelse.com");

assertThat(this.validateIdToken())
.hasSize(1)
Expand All @@ -114,9 +112,7 @@ public void validateWhenMetadataIssuerMatchThenNoErrors() {
* When the issuer is set in the provider metadata, and it does match the issuer in the ID Token,
* the validation must succeed
*/
Map<String, Object> configurationMetadata = new HashMap<>();
configurationMetadata.put("issuer", "https://issuer.example.com");
this.registration = this.registration.providerConfigurationMetadata(configurationMetadata);
this.registration = this.registration.issuerUri("https://issuer.example.com");

assertThat(this.validateIdToken()).isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ private void assertIssuerMetadata(ClientRegistration registration,
assertThat(provider.getAuthorizationUri()).isEqualTo("https://example.com/o/oauth2/v2/auth");
assertThat(provider.getTokenUri()).isEqualTo("https://example.com/oauth2/v4/token");
assertThat(provider.getJwkSetUri()).isEqualTo("https://example.com/oauth2/v3/certs");
assertThat(provider.getIssuerUri()).isEqualTo(this.issuer);
assertThat(provider.getConfigurationMetadata()).containsKeys("authorization_endpoint", "claims_supported",
"code_challenge_methods_supported", "id_token_signing_alg_values_supported", "issuer", "jwks_uri",
"response_types_supported", "revocation_endpoint", "scopes_supported", "subject_types_supported",
Expand Down