Skip to content

Commit 5412f10

Browse files
author
Steve Riesenberg
committed
Polish gh-489
1 parent 4081d46 commit 5412f10

File tree

9 files changed

+57
-26
lines changed

9 files changed

+57
-26
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/AbstractOAuth2AuthorizationServerMetadata.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -138,16 +138,6 @@ public B jwkSetUrl(String jwkSetUrl) {
138138
return claim(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI, jwkSetUrl);
139139
}
140140

141-
/**
142-
* Use this {@code userinfo_endpoint} in the resulting {@link AbstractOAuth2AuthorizationServerMetadata}, OPTIONAL.
143-
*
144-
* @param userInfoEndpoint the {@code URL} of the OAuth 2.0 UserInfo Endpoint
145-
* @return the {@link AbstractBuilder} for further configuration
146-
*/
147-
public B userInfoEndpoint(String userInfoEndpoint) {
148-
return claim(OAuth2AuthorizationServerMetadataClaimNames.USER_INFO_ENDPOINT, userInfoEndpoint);
149-
}
150-
151141
/**
152142
* Add this OAuth 2.0 {@code scope} to the collection of {@code scopes_supported}
153143
* in the resulting {@link AbstractOAuth2AuthorizationServerMetadata}, RECOMMENDED.
@@ -353,9 +343,6 @@ protected void validate() {
353343
if (getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI) != null) {
354344
validateURL(getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.JWKS_URI), "jwksUri must be a valid URL");
355345
}
356-
if (getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.USER_INFO_ENDPOINT) != null) {
357-
validateURL(getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.USER_INFO_ENDPOINT), "userInfoEndpoint must be a valid URL");
358-
}
359346
if (getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED) != null) {
360347
Assert.isInstanceOf(List.class, getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED), "scopes must be of type List");
361348
Assert.notEmpty((List<?>) getClaims().get(OAuth2AuthorizationServerMetadataClaimNames.SCOPES_SUPPORTED), "scopes cannot be empty");
@@ -404,7 +391,7 @@ private void acceptClaimValues(String name, Consumer<List<String>> valuesConsume
404391
valuesConsumer.accept(values);
405392
}
406393

407-
private static void validateURL(Object url, String errorMessage) {
394+
protected static void validateURL(Object url, String errorMessage) {
408395
if (URL.class.isAssignableFrom(url.getClass())) {
409396
return;
410397
}

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/OAuth2AuthorizationServerMetadataClaimNames.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ public interface OAuth2AuthorizationServerMetadataClaimNames {
5151
*/
5252
String JWKS_URI = "jwks_uri";
5353

54-
/**
55-
* {@code userinfo_endpoint} - the {@code URL} of the OAuth 2.0 UserInfo Endpoint
56-
*/
57-
String USER_INFO_ENDPOINT = "userinfo_endpoint";
58-
5954
/**
6055
* {@code scopes_supported} - the OAuth 2.0 {@code scope} values supported
6156
*/

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfiguration.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -118,6 +118,17 @@ public Builder idTokenSigningAlgorithms(Consumer<List<String>> signingAlgorithms
118118
return this;
119119
}
120120

121+
/**
122+
* Use this {@code userinfo_endpoint} in the resulting {@link OidcProviderConfiguration}, OPTIONAL.
123+
*
124+
* @param userInfoEndpoint the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint
125+
* @return the {@link Builder} for further configuration
126+
* @since 0.2.2
127+
*/
128+
public Builder userInfoEndpoint(String userInfoEndpoint) {
129+
return claim(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, userInfoEndpoint);
130+
}
131+
121132
/**
122133
* Validate the claims and build the {@link OidcProviderConfiguration}.
123134
* <p>
@@ -144,6 +155,9 @@ protected void validate() {
144155
Assert.notNull(getClaims().get(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED), "idTokenSigningAlgorithms cannot be null");
145156
Assert.isInstanceOf(List.class, getClaims().get(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED), "idTokenSigningAlgorithms must be of type List");
146157
Assert.notEmpty((List<?>) getClaims().get(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED), "idTokenSigningAlgorithms cannot be empty");
158+
if (getClaims().get(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT) != null) {
159+
validateURL(getClaims().get(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT), "userInfoEndpoint must be a valid URL");
160+
}
147161
}
148162

149163
@SuppressWarnings("unchecked")

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimAccessor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616
package org.springframework.security.oauth2.core.oidc;
1717

1818

19+
import java.net.URL;
1920
import java.util.List;
2021

2122
import org.springframework.security.oauth2.core.ClaimAccessor;
@@ -56,4 +57,14 @@ default List<String> getIdTokenSigningAlgorithms() {
5657
return getClaimAsStringList(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED);
5758
}
5859

60+
/**
61+
* Returns the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint {@code (userinfo_endpoint)}.
62+
*
63+
* @return the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint
64+
* @since 0.2.2
65+
*/
66+
default URL getUserInfoEndpoint() {
67+
return getClaimAsURL(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT);
68+
}
69+
5970
}

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/core/oidc/OidcProviderMetadataClaimNames.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,4 +39,10 @@ public interface OidcProviderMetadataClaimNames extends OAuth2AuthorizationServe
3939
*/
4040
String ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED = "id_token_signing_alg_values_supported";
4141

42+
/**
43+
* {@code userinfo_endpoint} - the {@code URL} of the OpenID Connect 1.0 UserInfo Endpoint
44+
* @since 0.2.2
45+
*/
46+
String USER_INFO_ENDPOINT = "userinfo_endpoint";
47+
4248
}

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
8888
.tokenEndpoint(asUrl(issuer, this.providerSettings.getTokenEndpoint()))
8989
.tokenEndpointAuthenticationMethods(clientAuthenticationMethods())
9090
.jwkSetUrl(asUrl(issuer, this.providerSettings.getJwkSetEndpoint()))
91-
.userInfoEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getOidcUserInfoEndpoint()))
91+
.userInfoEndpoint(asUrl(issuer, this.providerSettings.getOidcUserInfoEndpoint()))
9292
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
9393
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
9494
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationServerMetadataEndpointFilter.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
8686
.tokenEndpoint(asUrl(issuer, this.providerSettings.getTokenEndpoint()))
8787
.tokenEndpointAuthenticationMethods(clientAuthenticationMethods())
8888
.jwkSetUrl(asUrl(issuer, this.providerSettings.getJwkSetEndpoint()))
89-
.userInfoEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getOidcUserInfoEndpoint()))
9089
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
9190
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
9291
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/core/oidc/OidcProviderConfigurationTests.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2021 the original author or authors.
2+
* Copyright 2020-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -59,6 +59,7 @@ public void buildWhenAllRequiredClaimsAndAdditionalClaimsThenCreated() {
5959
.grantType("client_credentials")
6060
.subjectType("public")
6161
.idTokenSigningAlgorithm("RS256")
62+
.userInfoEndpoint("https://example.com/issuer1/userinfo")
6263
.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
6364
.claim("a-claim", "a-value")
6465
.build();
@@ -72,6 +73,7 @@ public void buildWhenAllRequiredClaimsAndAdditionalClaimsThenCreated() {
7273
assertThat(providerConfiguration.getGrantTypes()).containsExactlyInAnyOrder("authorization_code", "client_credentials");
7374
assertThat(providerConfiguration.getSubjectTypes()).containsExactly("public");
7475
assertThat(providerConfiguration.getIdTokenSigningAlgorithms()).containsExactly("RS256");
76+
assertThat(providerConfiguration.getUserInfoEndpoint()).isEqualTo(url("https://example.com/issuer1/userinfo"));
7577
assertThat(providerConfiguration.getTokenEndpointAuthenticationMethods()).containsExactly(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue());
7678
assertThat(providerConfiguration.<String>getClaim("a-claim")).isEqualTo("a-value");
7779
}
@@ -112,6 +114,7 @@ public void buildWhenClaimsProvidedThenCreated() {
112114
claims.put(OidcProviderMetadataClaimNames.RESPONSE_TYPES_SUPPORTED, Collections.singletonList("code"));
113115
claims.put(OidcProviderMetadataClaimNames.SUBJECT_TYPES_SUPPORTED, Collections.singletonList("public"));
114116
claims.put(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED, Collections.singletonList("RS256"));
117+
claims.put(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, "https://example.com/issuer1/userinfo");
115118
claims.put("some-claim", "some-value");
116119

117120
OidcProviderConfiguration providerConfiguration = OidcProviderConfiguration.withClaims(claims).build();
@@ -125,6 +128,7 @@ public void buildWhenClaimsProvidedThenCreated() {
125128
assertThat(providerConfiguration.getGrantTypes()).isNull();
126129
assertThat(providerConfiguration.getSubjectTypes()).containsExactly("public");
127130
assertThat(providerConfiguration.getIdTokenSigningAlgorithms()).containsExactly("RS256");
131+
assertThat(providerConfiguration.getUserInfoEndpoint()).isEqualTo(url("https://example.com/issuer1/userinfo"));
128132
assertThat(providerConfiguration.getTokenEndpointAuthenticationMethods()).isNull();
129133
assertThat(providerConfiguration.<String>getClaim("some-claim")).isEqualTo("some-value");
130134
}
@@ -140,6 +144,7 @@ public void buildWhenClaimsProvidedWithUrlsThenCreated() {
140144
claims.put(OidcProviderMetadataClaimNames.RESPONSE_TYPES_SUPPORTED, Collections.singletonList("code"));
141145
claims.put(OidcProviderMetadataClaimNames.SUBJECT_TYPES_SUPPORTED, Collections.singletonList("public"));
142146
claims.put(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED, Collections.singletonList("RS256"));
147+
claims.put(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, url("https://example.com/issuer1/userinfo"));
143148
claims.put("some-claim", "some-value");
144149

145150
OidcProviderConfiguration providerConfiguration = OidcProviderConfiguration.withClaims(claims).build();
@@ -153,6 +158,7 @@ public void buildWhenClaimsProvidedWithUrlsThenCreated() {
153158
assertThat(providerConfiguration.getGrantTypes()).isNull();
154159
assertThat(providerConfiguration.getSubjectTypes()).containsExactly("public");
155160
assertThat(providerConfiguration.getIdTokenSigningAlgorithms()).containsExactly("RS256");
161+
assertThat(providerConfiguration.getUserInfoEndpoint()).isEqualTo(url("https://example.com/issuer1/userinfo"));
156162
assertThat(providerConfiguration.getTokenEndpointAuthenticationMethods()).isNull();
157163
assertThat(providerConfiguration.<String>getClaim("some-claim")).isEqualTo("some-value");
158164
}
@@ -380,6 +386,16 @@ public void buildWhenIdTokenSigningAlgorithmsEmptyListThenThrowIllegalArgumentEx
380386
.withMessageContaining("idTokenSigningAlgorithms cannot be empty");
381387
}
382388

389+
@Test
390+
public void buildWhenUserInfoEndpointNotUrlThenThrowIllegalArgumentException() {
391+
OidcProviderConfiguration.Builder builder = this.minimalConfigurationBuilder
392+
.claims((claims) -> claims.put(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, "not an url"));
393+
394+
assertThatIllegalArgumentException()
395+
.isThrownBy(builder::build)
396+
.withMessage("userInfoEndpoint must be a valid URL");
397+
}
398+
383399
@Test
384400
public void responseTypesWhenAddingOrRemovingThenCorrectValues() {
385401
OidcProviderConfiguration configuration = this.minimalConfigurationBuilder

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/web/OidcProviderConfigurationEndpointFilterTests.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,14 @@ public void doFilterWhenConfigurationRequestThenConfigurationResponse() throws E
9494
String authorizationEndpoint = "/oauth2/v1/authorize";
9595
String tokenEndpoint = "/oauth2/v1/token";
9696
String jwkSetEndpoint = "/oauth2/v1/jwks";
97+
String userInfoEndpoint = "/userinfo";
9798

9899
ProviderSettings providerSettings = ProviderSettings.builder()
99100
.issuer(issuer)
100101
.authorizationEndpoint(authorizationEndpoint)
101102
.tokenEndpoint(tokenEndpoint)
102103
.jwkSetEndpoint(jwkSetEndpoint)
104+
.oidcUserInfoEndpoint(userInfoEndpoint)
103105
.build();
104106
ProviderContextHolder.setProviderContext(new ProviderContext(providerSettings, null));
105107
OidcProviderConfigurationEndpointFilter filter =
@@ -126,6 +128,7 @@ public void doFilterWhenConfigurationRequestThenConfigurationResponse() throws E
126128
assertThat(providerConfigurationResponse).contains("\"grant_types_supported\":[\"authorization_code\",\"client_credentials\",\"refresh_token\"]");
127129
assertThat(providerConfigurationResponse).contains("\"subject_types_supported\":[\"public\"]");
128130
assertThat(providerConfigurationResponse).contains("\"id_token_signing_alg_values_supported\":[\"RS256\"]");
131+
assertThat(providerConfigurationResponse).contains("\"userinfo_endpoint\":\"https://example.com/issuer1/userinfo\"");
129132
assertThat(providerConfigurationResponse).contains("\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"client_secret_post\",\"client_secret_jwt\",\"private_key_jwt\"]");
130133
}
131134

0 commit comments

Comments
 (0)