diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2AuthorizationServerMetadata.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2AuthorizationServerMetadata.java index 66916c54..8d73943b 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2AuthorizationServerMetadata.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2AuthorizationServerMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -138,16 +138,6 @@ public abstract class AbstractOAuth2AuthorizationServerMetadata implements OAuth return claim(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI, jwkSetUrl); } - /** - * Use this {@code userinfo_endpoint} in the resulting {@link AbstractOAuth2AuthorizationServerMetadata}, OPTIONAL. - * - * @param userInfoEndpoint the {@code URL} of the OAuth 2.0 UserInfo Endpoint - * @return the {@link AbstractBuilder} for further configuration - */ - public B userInfoEndpoint(String userInfoEndpoint) { - return claim(OAuth2AuthorizationServerMetadataClaimNames.USER_INFO_ENDPOINT, userInfoEndpoint); - } - /** * Add this OAuth 2.0 {@code scope} to the collection of {@code scopes_supported} * in the resulting {@link AbstractOAuth2AuthorizationServerMetadata}, RECOMMENDED. @@ -353,9 +343,6 @@ public abstract class AbstractOAuth2AuthorizationServerMetadata implements OAuth if (getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI) != null) { validateURL(getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI), "jwksUri must be a valid URL"); } - if (getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.USER_INFO_ENDPOINT) != null) { - validateURL(getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.USER_INFO_ENDPOINT), "userInfoEndpoint must be a valid URL"); - } if (getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED) != null) { Assert.isInstanceOf(List.class, getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED), "scopes must be of type List"); Assert.notEmpty((List>) getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED), "scopes cannot be empty"); @@ -404,7 +391,7 @@ public abstract class AbstractOAuth2AuthorizationServerMetadata implements OAuth valuesConsumer.accept(values); } - private static void validateURL(Object url, String errorMessage) { + protected static void validateURL(Object url, String errorMessage) { if (URL.class.isAssignableFrom(url.getClass())) { return; } diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/OAuth2AuthorizationServerMetadataClaimNames.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/OAuth2AuthorizationServerMetadataClaimNames.java index e64d530c..e6bd62be 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/OAuth2AuthorizationServerMetadataClaimNames.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/OAuth2AuthorizationServerMetadataClaimNames.java @@ -51,11 +51,6 @@ public interface OAuth2AuthorizationServerMetadataClaimNames { */ String JWKS_URI = "jwks_uri"; - /** - * {@code userinfo_endpoint} - the {@code URL} of the OAuth 2.0 UserInfo Endpoint - */ - String USER_INFO_ENDPOINT = "userinfo_endpoint"; - /** * {@code scopes_supported} - the OAuth 2.0 {@code scope} values supported */ diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfiguration.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfiguration.java index 20c690e8..afe93787 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfiguration.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -118,6 +118,17 @@ public final class OidcProviderConfiguration extends AbstractOAuth2Authorization return this; } + /** + * Use this {@code userinfo_endpoint} in the resulting {@link OidcProviderConfiguration}, OPTIONAL. + * + * @param userInfoEndpoint the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint + * @return the {@link Builder} for further configuration + * @since 0.2.2 + */ + public Builder userInfoEndpoint(String userInfoEndpoint) { + return claim(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, userInfoEndpoint); + } + /** * Validate the claims and build the {@link OidcProviderConfiguration}. *
@@ -144,6 +155,9 @@ public final class OidcProviderConfiguration extends AbstractOAuth2Authorization
Assert.notNull(getClaims().get(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED), "idTokenSigningAlgorithms cannot be null");
Assert.isInstanceOf(List.class, getClaims().get(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED), "idTokenSigningAlgorithms must be of type List");
Assert.notEmpty((List>) getClaims().get(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED), "idTokenSigningAlgorithms cannot be empty");
+ if (getClaims().get(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT) != null) {
+ validateURL(getClaims().get(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT), "userInfoEndpoint must be a valid URL");
+ }
}
@SuppressWarnings("unchecked")
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimAccessor.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimAccessor.java
index c30a94d0..4aec61ee 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimAccessor.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimAccessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2021 the original author or authors.
+ * Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.security.oauth2.core.oidc;
+import java.net.URL;
import java.util.List;
import org.springframework.security.oauth2.core.ClaimAccessor;
@@ -56,4 +57,14 @@ public interface OidcProviderMetadataClaimAccessor extends OAuth2AuthorizationSe
return getClaimAsStringList(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED);
}
+ /**
+ * Returns the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint {@code (userinfo_endpoint)}.
+ *
+ * @return the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint
+ * @since 0.2.2
+ */
+ default URL getUserInfoEndpoint() {
+ return getClaimAsURL(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT);
+ }
+
}
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimNames.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimNames.java
index ef3722be..d77a53f7 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimNames.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimNames.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2021 the original author or authors.
+ * Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,4 +39,10 @@ public interface OidcProviderMetadataClaimNames extends OAuth2AuthorizationServe
*/
String ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED = "id_token_signing_alg_values_supported";
+ /**
+ * {@code userinfo_endpoint} - the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint
+ * @since 0.2.2
+ */
+ String USER_INFO_ENDPOINT = "userinfo_endpoint";
+
}
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java
index 1645617c..cc3e7290 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java
@@ -88,7 +88,7 @@ public final class OidcProviderConfigurationEndpointFilter extends OncePerReques
.tokenEndpoint(asUrl(issuer, this.providerSettings.getTokenEndpoint()))
.tokenEndpointAuthenticationMethods(clientAuthenticationMethods())
.jwkSetUrl(asUrl(issuer, this.providerSettings.getJwkSetEndpoint()))
- .userInfoEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getOidcUserInfoEndpoint()))
+ .userInfoEndpoint(asUrl(issuer, this.providerSettings.getOidcUserInfoEndpoint()))
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java
index 10837b3b..efb690a6 100644
--- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java
+++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java
@@ -86,7 +86,6 @@ public final class OAuth2AuthorizationServerMetadataEndpointFilter extends OnceP
.tokenEndpoint(asUrl(issuer, this.providerSettings.getTokenEndpoint()))
.tokenEndpointAuthenticationMethods(clientAuthenticationMethods())
.jwkSetUrl(asUrl(issuer, this.providerSettings.getJwkSetEndpoint()))
- .userInfoEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getOidcUserInfoEndpoint()))
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfigurationTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfigurationTests.java
index add0b4e9..22562aeb 100644
--- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfigurationTests.java
+++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfigurationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2020-2021 the original author or authors.
+ * Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,6 +59,7 @@ public class OidcProviderConfigurationTests {
.grantType("client_credentials")
.subjectType("public")
.idTokenSigningAlgorithm("RS256")
+ .userInfoEndpoint("https://example.com/issuer1/userinfo")
.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
.claim("a-claim", "a-value")
.build();
@@ -72,6 +73,7 @@ public class OidcProviderConfigurationTests {
assertThat(providerConfiguration.getGrantTypes()).containsExactlyInAnyOrder("authorization_code", "client_credentials");
assertThat(providerConfiguration.getSubjectTypes()).containsExactly("public");
assertThat(providerConfiguration.getIdTokenSigningAlgorithms()).containsExactly("RS256");
+ assertThat(providerConfiguration.getUserInfoEndpoint()).isEqualTo(url("https://example.com/issuer1/userinfo"));
assertThat(providerConfiguration.getTokenEndpointAuthenticationMethods()).containsExactly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue());
assertThat(providerConfiguration.