Polish gh-489
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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}.
|
||||
* <p>
|
||||
@@ -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")
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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.<String>getClaim("a-claim")).isEqualTo("a-value");
|
||||
}
|
||||
@@ -112,6 +114,7 @@ public class OidcProviderConfigurationTests {
|
||||
claims.put(OidcProviderMetadataClaimNames.RESPONSE_TYPES_SUPPORTED, Collections.singletonList("code"));
|
||||
claims.put(OidcProviderMetadataClaimNames.SUBJECT_TYPES_SUPPORTED, Collections.singletonList("public"));
|
||||
claims.put(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED, Collections.singletonList("RS256"));
|
||||
claims.put(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, "https://example.com/issuer1/userinfo");
|
||||
claims.put("some-claim", "some-value");
|
||||
|
||||
OidcProviderConfiguration providerConfiguration = OidcProviderConfiguration.withClaims(claims).build();
|
||||
@@ -125,6 +128,7 @@ public class OidcProviderConfigurationTests {
|
||||
assertThat(providerConfiguration.getGrantTypes()).isNull();
|
||||
assertThat(providerConfiguration.getSubjectTypes()).containsExactly("public");
|
||||
assertThat(providerConfiguration.getIdTokenSigningAlgorithms()).containsExactly("RS256");
|
||||
assertThat(providerConfiguration.getUserInfoEndpoint()).isEqualTo(url("https://example.com/issuer1/userinfo"));
|
||||
assertThat(providerConfiguration.getTokenEndpointAuthenticationMethods()).isNull();
|
||||
assertThat(providerConfiguration.<String>getClaim("some-claim")).isEqualTo("some-value");
|
||||
}
|
||||
@@ -140,6 +144,7 @@ public class OidcProviderConfigurationTests {
|
||||
claims.put(OidcProviderMetadataClaimNames.RESPONSE_TYPES_SUPPORTED, Collections.singletonList("code"));
|
||||
claims.put(OidcProviderMetadataClaimNames.SUBJECT_TYPES_SUPPORTED, Collections.singletonList("public"));
|
||||
claims.put(OidcProviderMetadataClaimNames.ID_TOKEN_SIGNING_ALG_VALUES_SUPPORTED, Collections.singletonList("RS256"));
|
||||
claims.put(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, url("https://example.com/issuer1/userinfo"));
|
||||
claims.put("some-claim", "some-value");
|
||||
|
||||
OidcProviderConfiguration providerConfiguration = OidcProviderConfiguration.withClaims(claims).build();
|
||||
@@ -153,6 +158,7 @@ public class OidcProviderConfigurationTests {
|
||||
assertThat(providerConfiguration.getGrantTypes()).isNull();
|
||||
assertThat(providerConfiguration.getSubjectTypes()).containsExactly("public");
|
||||
assertThat(providerConfiguration.getIdTokenSigningAlgorithms()).containsExactly("RS256");
|
||||
assertThat(providerConfiguration.getUserInfoEndpoint()).isEqualTo(url("https://example.com/issuer1/userinfo"));
|
||||
assertThat(providerConfiguration.getTokenEndpointAuthenticationMethods()).isNull();
|
||||
assertThat(providerConfiguration.<String>getClaim("some-claim")).isEqualTo("some-value");
|
||||
}
|
||||
@@ -380,6 +386,16 @@ public class OidcProviderConfigurationTests {
|
||||
.withMessageContaining("idTokenSigningAlgorithms cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildWhenUserInfoEndpointNotUrlThenThrowIllegalArgumentException() {
|
||||
OidcProviderConfiguration.Builder builder = this.minimalConfigurationBuilder
|
||||
.claims((claims) -> claims.put(OidcProviderMetadataClaimNames.USER_INFO_ENDPOINT, "not an url"));
|
||||
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(builder::build)
|
||||
.withMessage("userInfoEndpoint must be a valid URL");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void responseTypesWhenAddingOrRemovingThenCorrectValues() {
|
||||
OidcProviderConfiguration configuration = this.minimalConfigurationBuilder
|
||||
|
||||
@@ -94,12 +94,14 @@ public class OidcProviderConfigurationEndpointFilterTests {
|
||||
String authorizationEndpoint = "/oauth2/v1/authorize";
|
||||
String tokenEndpoint = "/oauth2/v1/token";
|
||||
String jwkSetEndpoint = "/oauth2/v1/jwks";
|
||||
String userInfoEndpoint = "/userinfo";
|
||||
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.issuer(issuer)
|
||||
.authorizationEndpoint(authorizationEndpoint)
|
||||
.tokenEndpoint(tokenEndpoint)
|
||||
.jwkSetEndpoint(jwkSetEndpoint)
|
||||
.oidcUserInfoEndpoint(userInfoEndpoint)
|
||||
.build();
|
||||
ProviderContextHolder.setProviderContext(new ProviderContext(providerSettings, null));
|
||||
OidcProviderConfigurationEndpointFilter filter =
|
||||
@@ -126,6 +128,7 @@ public class OidcProviderConfigurationEndpointFilterTests {
|
||||
assertThat(providerConfigurationResponse).contains("\"grant_types_supported\":[\"authorization_code\",\"client_credentials\",\"refresh_token\"]");
|
||||
assertThat(providerConfigurationResponse).contains("\"subject_types_supported\":[\"public\"]");
|
||||
assertThat(providerConfigurationResponse).contains("\"id_token_signing_alg_values_supported\":[\"RS256\"]");
|
||||
assertThat(providerConfigurationResponse).contains("\"userinfo_endpoint\":\"https://example.com/issuer1/userinfo\"");
|
||||
assertThat(providerConfigurationResponse).contains("\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"client_secret_post\",\"client_secret_jwt\",\"private_key_jwt\"]");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user