Make Settings implementations immutable
Closes gh-366
This commit is contained in:
@@ -130,7 +130,7 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C
|
||||
*
|
||||
* <ul>
|
||||
* <li>It must be an HTTP POST</li>
|
||||
* <li>It must be submitted to {@link ProviderSettings#authorizationEndpoint()}</li>
|
||||
* <li>It must be submitted to {@link ProviderSettings#getAuthorizationEndpoint()} ()}</li>
|
||||
* <li>It must include the received {@code client_id} as an HTTP parameter</li>
|
||||
* <li>It must include the received {@code state} as an HTTP parameter</li>
|
||||
* <li>It must include the list of {@code scope}s the {@code Resource Owner}
|
||||
@@ -150,10 +150,10 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C
|
||||
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
|
||||
this.requestMatcher = new OrRequestMatcher(
|
||||
new AntPathRequestMatcher(
|
||||
providerSettings.authorizationEndpoint(),
|
||||
providerSettings.getAuthorizationEndpoint(),
|
||||
HttpMethod.GET.name()),
|
||||
new AntPathRequestMatcher(
|
||||
providerSettings.authorizationEndpoint(),
|
||||
providerSettings.getAuthorizationEndpoint(),
|
||||
HttpMethod.POST.name()));
|
||||
|
||||
List<AuthenticationProvider> authenticationProviders =
|
||||
@@ -172,7 +172,7 @@ public final class OAuth2AuthorizationEndpointConfigurer extends AbstractOAuth2C
|
||||
OAuth2AuthorizationEndpointFilter authorizationEndpointFilter =
|
||||
new OAuth2AuthorizationEndpointFilter(
|
||||
authenticationManager,
|
||||
providerSettings.authorizationEndpoint());
|
||||
providerSettings.getAuthorizationEndpoint());
|
||||
if (this.authorizationRequestConverter != null) {
|
||||
authorizationEndpointFilter.setAuthenticationConverter(this.authorizationRequestConverter);
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
|
||||
this.configurers.values().forEach(configurer -> configurer.configure(builder));
|
||||
|
||||
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
|
||||
if (providerSettings.issuer() != null) {
|
||||
if (providerSettings.getIssuer() != null) {
|
||||
OidcProviderConfigurationEndpointFilter oidcProviderConfigurationEndpointFilter =
|
||||
new OidcProviderConfigurationEndpointFilter(providerSettings);
|
||||
builder.addFilterBefore(postProcess(oidcProviderConfigurationEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
|
||||
@@ -240,7 +240,7 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
|
||||
JWKSource<SecurityContext> jwkSource = OAuth2ConfigurerUtils.getJwkSource(builder);
|
||||
NimbusJwkSetEndpointFilter jwkSetEndpointFilter = new NimbusJwkSetEndpointFilter(
|
||||
jwkSource,
|
||||
providerSettings.jwkSetEndpoint());
|
||||
providerSettings.getJwkSetEndpoint());
|
||||
builder.addFilterBefore(postProcess(jwkSetEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
|
||||
|
||||
AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class);
|
||||
@@ -257,20 +257,20 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
|
||||
OAuth2TokenIntrospectionEndpointFilter tokenIntrospectionEndpointFilter =
|
||||
new OAuth2TokenIntrospectionEndpointFilter(
|
||||
authenticationManager,
|
||||
providerSettings.tokenIntrospectionEndpoint());
|
||||
providerSettings.getTokenIntrospectionEndpoint());
|
||||
builder.addFilterAfter(postProcess(tokenIntrospectionEndpointFilter), FilterSecurityInterceptor.class);
|
||||
|
||||
OAuth2TokenRevocationEndpointFilter tokenRevocationEndpointFilter =
|
||||
new OAuth2TokenRevocationEndpointFilter(
|
||||
authenticationManager,
|
||||
providerSettings.tokenRevocationEndpoint());
|
||||
providerSettings.getTokenRevocationEndpoint());
|
||||
builder.addFilterAfter(postProcess(tokenRevocationEndpointFilter), OAuth2TokenIntrospectionEndpointFilter.class);
|
||||
|
||||
// TODO Make OpenID Client Registration an "opt-in" feature
|
||||
OidcClientRegistrationEndpointFilter oidcClientRegistrationEndpointFilter =
|
||||
new OidcClientRegistrationEndpointFilter(
|
||||
authenticationManager,
|
||||
providerSettings.oidcClientRegistrationEndpoint());
|
||||
providerSettings.getOidcClientRegistrationEndpoint());
|
||||
builder.addFilterAfter(postProcess(oidcClientRegistrationEndpointFilter), OAuth2TokenRevocationEndpointFilter.class);
|
||||
}
|
||||
|
||||
@@ -292,23 +292,23 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
|
||||
|
||||
private void initEndpointMatchers(ProviderSettings providerSettings) {
|
||||
this.tokenIntrospectionEndpointMatcher = new AntPathRequestMatcher(
|
||||
providerSettings.tokenIntrospectionEndpoint(), HttpMethod.POST.name());
|
||||
providerSettings.getTokenIntrospectionEndpoint(), HttpMethod.POST.name());
|
||||
this.tokenRevocationEndpointMatcher = new AntPathRequestMatcher(
|
||||
providerSettings.tokenRevocationEndpoint(), HttpMethod.POST.name());
|
||||
providerSettings.getTokenRevocationEndpoint(), HttpMethod.POST.name());
|
||||
this.jwkSetEndpointMatcher = new AntPathRequestMatcher(
|
||||
providerSettings.jwkSetEndpoint(), HttpMethod.GET.name());
|
||||
providerSettings.getJwkSetEndpoint(), HttpMethod.GET.name());
|
||||
this.oidcProviderConfigurationEndpointMatcher = new AntPathRequestMatcher(
|
||||
"/.well-known/openid-configuration", HttpMethod.GET.name());
|
||||
this.authorizationServerMetadataEndpointMatcher = new AntPathRequestMatcher(
|
||||
"/.well-known/oauth-authorization-server", HttpMethod.GET.name());
|
||||
this.oidcClientRegistrationEndpointMatcher = new AntPathRequestMatcher(
|
||||
providerSettings.oidcClientRegistrationEndpoint(), HttpMethod.POST.name());
|
||||
providerSettings.getOidcClientRegistrationEndpoint(), HttpMethod.POST.name());
|
||||
}
|
||||
|
||||
private static void validateProviderSettings(ProviderSettings providerSettings) {
|
||||
if (providerSettings.issuer() != null) {
|
||||
if (providerSettings.getIssuer() != null) {
|
||||
try {
|
||||
new URI(providerSettings.issuer()).toURL();
|
||||
new URI(providerSettings.getIssuer()).toURL();
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("issuer must be a valid URL", ex);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ final class OAuth2ConfigurerUtils {
|
||||
if (providerSettings == null) {
|
||||
providerSettings = getOptionalBean(builder, ProviderSettings.class);
|
||||
if (providerSettings == null) {
|
||||
providerSettings = new ProviderSettings();
|
||||
providerSettings = ProviderSettings.builder().build();
|
||||
}
|
||||
builder.setSharedObject(ProviderSettings.class, providerSettings);
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public final class OAuth2TokenEndpointConfigurer extends AbstractOAuth2Configure
|
||||
<B extends HttpSecurityBuilder<B>> void init(B builder) {
|
||||
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
|
||||
this.requestMatcher = new AntPathRequestMatcher(
|
||||
providerSettings.tokenEndpoint(), HttpMethod.POST.name());
|
||||
providerSettings.getTokenEndpoint(), HttpMethod.POST.name());
|
||||
|
||||
List<AuthenticationProvider> authenticationProviders =
|
||||
!this.authenticationProviders.isEmpty() ?
|
||||
@@ -137,7 +137,7 @@ public final class OAuth2TokenEndpointConfigurer extends AbstractOAuth2Configure
|
||||
OAuth2TokenEndpointFilter tokenEndpointFilter =
|
||||
new OAuth2TokenEndpointFilter(
|
||||
authenticationManager,
|
||||
providerSettings.tokenEndpoint());
|
||||
providerSettings.getTokenEndpoint());
|
||||
if (this.accessTokenRequestConverter != null) {
|
||||
tokenEndpointFilter.setAuthenticationConverter(this.accessTokenRequestConverter);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ final class JwtUtils {
|
||||
String issuer, String subject, Set<String> authorizedScopes) {
|
||||
|
||||
Instant issuedAt = Instant.now();
|
||||
Instant expiresAt = issuedAt.plus(registeredClient.getTokenSettings().accessTokenTimeToLive());
|
||||
Instant expiresAt = issuedAt.plus(registeredClient.getTokenSettings().getAccessTokenTimeToLive());
|
||||
|
||||
// @formatter:off
|
||||
JwtClaimsSet.Builder claimsBuilder = JwtClaimsSet.builder();
|
||||
|
||||
@@ -140,7 +140,7 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth
|
||||
throw new OAuth2AuthenticationException(new OAuth2Error(OAuth2ErrorCodes.INVALID_GRANT));
|
||||
}
|
||||
|
||||
String issuer = this.providerSettings != null ? this.providerSettings.issuer() : null;
|
||||
String issuer = this.providerSettings != null ? this.providerSettings.getIssuer() : null;
|
||||
Set<String> authorizedScopes = authorization.getAttribute(
|
||||
OAuth2Authorization.AUTHORIZED_SCOPE_ATTRIBUTE_NAME);
|
||||
|
||||
@@ -174,7 +174,7 @@ public final class OAuth2AuthorizationCodeAuthenticationProvider implements Auth
|
||||
OAuth2RefreshToken refreshToken = null;
|
||||
if (registeredClient.getAuthorizationGrantTypes().contains(AuthorizationGrantType.REFRESH_TOKEN)) {
|
||||
refreshToken = OAuth2RefreshTokenAuthenticationProvider.generateRefreshToken(
|
||||
registeredClient.getTokenSettings().refreshTokenTimeToLive());
|
||||
registeredClient.getTokenSettings().getRefreshTokenTimeToLive());
|
||||
}
|
||||
|
||||
Jwt jwtIdToken = null;
|
||||
|
||||
@@ -151,7 +151,7 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen
|
||||
authorizationCodeRequestAuthentication, registeredClient, null);
|
||||
}
|
||||
}
|
||||
} else if (registeredClient.getClientSettings().requireProofKey()) {
|
||||
} else if (registeredClient.getClientSettings().isRequireProofKey()) {
|
||||
throwError(OAuth2ErrorCodes.INVALID_REQUEST, PkceParameterNames.CODE_CHALLENGE, PKCE_ERROR_URI,
|
||||
authorizationCodeRequestAuthentication, registeredClient, null);
|
||||
}
|
||||
@@ -341,7 +341,7 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationProvider implemen
|
||||
private static boolean requireAuthorizationConsent(RegisteredClient registeredClient,
|
||||
OAuth2AuthorizationRequest authorizationRequest, OAuth2AuthorizationConsent authorizationConsent) {
|
||||
|
||||
if (!registeredClient.getClientSettings().requireAuthorizationConsent()) {
|
||||
if (!registeredClient.getClientSettings().isRequireAuthorizationConsent()) {
|
||||
return false;
|
||||
}
|
||||
// 'openid' scope does not require consent
|
||||
|
||||
@@ -150,7 +150,7 @@ public final class OAuth2ClientAuthenticationProvider implements AuthenticationP
|
||||
String codeChallenge = (String) authorizationRequest.getAdditionalParameters()
|
||||
.get(PkceParameterNames.CODE_CHALLENGE);
|
||||
if (!StringUtils.hasText(codeChallenge) &&
|
||||
registeredClient.getClientSettings().requireProofKey()) {
|
||||
registeredClient.getClientSettings().isRequireProofKey()) {
|
||||
throwInvalidClient();
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ public final class OAuth2ClientCredentialsAuthenticationProvider implements Auth
|
||||
authorizedScopes = new LinkedHashSet<>(clientCredentialsAuthentication.getScopes());
|
||||
}
|
||||
|
||||
String issuer = this.providerSettings != null ? this.providerSettings.issuer() : null;
|
||||
String issuer = this.providerSettings != null ? this.providerSettings.getIssuer() : null;
|
||||
|
||||
JoseHeader.Builder headersBuilder = JwtUtils.headers();
|
||||
JwtClaimsSet.Builder claimsBuilder = JwtUtils.accessTokenClaims(
|
||||
|
||||
@@ -147,7 +147,7 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic
|
||||
scopes = authorizedScopes;
|
||||
}
|
||||
|
||||
String issuer = this.providerSettings != null ? this.providerSettings.issuer() : null;
|
||||
String issuer = this.providerSettings != null ? this.providerSettings.getIssuer() : null;
|
||||
|
||||
JoseHeader.Builder headersBuilder = JwtUtils.headers();
|
||||
JwtClaimsSet.Builder claimsBuilder = JwtUtils.accessTokenClaims(
|
||||
@@ -178,8 +178,8 @@ public final class OAuth2RefreshTokenAuthenticationProvider implements Authentic
|
||||
TokenSettings tokenSettings = registeredClient.getTokenSettings();
|
||||
|
||||
OAuth2RefreshToken currentRefreshToken = refreshToken.getToken();
|
||||
if (!tokenSettings.reuseRefreshTokens()) {
|
||||
currentRefreshToken = generateRefreshToken(tokenSettings.refreshTokenTimeToLive());
|
||||
if (!tokenSettings.isReuseRefreshTokens()) {
|
||||
currentRefreshToken = generateRefreshToken(tokenSettings.getRefreshTokenTimeToLive());
|
||||
}
|
||||
|
||||
Jwt jwtIdToken = null;
|
||||
|
||||
@@ -39,6 +39,8 @@ import org.springframework.jdbc.core.SqlParameterValue;
|
||||
import org.springframework.security.jackson2.SecurityJackson2Modules;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -211,12 +213,10 @@ public class JdbcRegisteredClientRepository implements RegisteredClientRepositor
|
||||
// @formatter:on
|
||||
|
||||
Map<String, Object> clientSettingsMap = parseMap(rs.getString("client_settings"));
|
||||
builder.clientSettings(clientSettings ->
|
||||
clientSettings.settings().putAll(clientSettingsMap));
|
||||
builder.clientSettings(ClientSettings.withSettings(clientSettingsMap).build());
|
||||
|
||||
Map<String, Object> tokenSettingsMap = parseMap(rs.getString("token_settings"));
|
||||
builder.tokenSettings(tokenSettings ->
|
||||
tokenSettings.settings().putAll(tokenSettingsMap));
|
||||
builder.tokenSettings(TokenSettings.withSettings(tokenSettingsMap).build());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@@ -303,8 +303,8 @@ public class JdbcRegisteredClientRepository implements RegisteredClientRepositor
|
||||
new SqlParameterValue(Types.VARCHAR, StringUtils.collectionToCommaDelimitedString(authorizationGrantTypes)),
|
||||
new SqlParameterValue(Types.VARCHAR, StringUtils.collectionToCommaDelimitedString(registeredClient.getRedirectUris())),
|
||||
new SqlParameterValue(Types.VARCHAR, StringUtils.collectionToCommaDelimitedString(registeredClient.getScopes())),
|
||||
new SqlParameterValue(Types.VARCHAR, writeMap(registeredClient.getClientSettings().settings())),
|
||||
new SqlParameterValue(Types.VARCHAR, writeMap(registeredClient.getTokenSettings().settings())));
|
||||
new SqlParameterValue(Types.VARCHAR, writeMap(registeredClient.getClientSettings().getSettings())),
|
||||
new SqlParameterValue(Types.VARCHAR, writeMap(registeredClient.getTokenSettings().getSettings())));
|
||||
}
|
||||
|
||||
public final void setObjectMapper(ObjectMapper objectMapper) {
|
||||
|
||||
@@ -190,15 +190,15 @@ public class RegisteredClient implements Serializable {
|
||||
Objects.equals(this.authorizationGrantTypes, that.authorizationGrantTypes) &&
|
||||
Objects.equals(this.redirectUris, that.redirectUris) &&
|
||||
Objects.equals(this.scopes, that.scopes) &&
|
||||
Objects.equals(this.clientSettings.settings(), that.getClientSettings().settings()) &&
|
||||
Objects.equals(this.tokenSettings.settings(), that.tokenSettings.settings());
|
||||
Objects.equals(this.clientSettings, that.clientSettings) &&
|
||||
Objects.equals(this.tokenSettings, that.tokenSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.id, this.clientId, this.clientIdIssuedAt, this.clientSecret, this.clientSecretExpiresAt,
|
||||
this.clientName, this.clientAuthenticationMethods, this.authorizationGrantTypes, this.redirectUris,
|
||||
this.scopes, this.clientSettings.settings(), this.tokenSettings.settings());
|
||||
this.scopes, this.clientSettings, this.tokenSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,8 +211,8 @@ public class RegisteredClient implements Serializable {
|
||||
", authorizationGrantTypes=" + this.authorizationGrantTypes +
|
||||
", redirectUris=" + this.redirectUris +
|
||||
", scopes=" + this.scopes +
|
||||
", clientSettings=" + this.clientSettings.settings() +
|
||||
", tokenSettings=" + this.tokenSettings.settings() +
|
||||
", clientSettings=" + this.clientSettings +
|
||||
", tokenSettings=" + this.tokenSettings +
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -253,8 +253,8 @@ public class RegisteredClient implements Serializable {
|
||||
private Set<AuthorizationGrantType> authorizationGrantTypes = new HashSet<>();
|
||||
private Set<String> redirectUris = new HashSet<>();
|
||||
private Set<String> scopes = new HashSet<>();
|
||||
private ClientSettings clientSettings = new ClientSettings();
|
||||
private TokenSettings tokenSettings = new TokenSettings();
|
||||
private ClientSettings clientSettings;
|
||||
private TokenSettings tokenSettings;
|
||||
|
||||
protected Builder(String id) {
|
||||
this.id = id;
|
||||
@@ -279,8 +279,8 @@ public class RegisteredClient implements Serializable {
|
||||
if (!CollectionUtils.isEmpty(registeredClient.scopes)) {
|
||||
this.scopes.addAll(registeredClient.scopes);
|
||||
}
|
||||
this.clientSettings = new ClientSettings(registeredClient.clientSettings.settings());
|
||||
this.tokenSettings = new TokenSettings(registeredClient.tokenSettings.settings());
|
||||
this.clientSettings = ClientSettings.withSettings(registeredClient.getClientSettings().getSettings()).build();
|
||||
this.tokenSettings = TokenSettings.withSettings(registeredClient.getTokenSettings().getSettings()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,26 +444,24 @@ public class RegisteredClient implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link Consumer} of the client configuration settings,
|
||||
* allowing the ability to add, replace, or remove.
|
||||
* Sets the {@link ClientSettings client configuration settings}.
|
||||
*
|
||||
* @param clientSettingsConsumer a {@link Consumer} of the client configuration settings
|
||||
* @param clientSettings the client configuration settings
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public Builder clientSettings(Consumer<ClientSettings> clientSettingsConsumer) {
|
||||
clientSettingsConsumer.accept(this.clientSettings);
|
||||
public Builder clientSettings(ClientSettings clientSettings) {
|
||||
this.clientSettings = clientSettings;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link Consumer} of the token configuration settings,
|
||||
* allowing the ability to add, replace, or remove.
|
||||
* Sets the {@link TokenSettings token configuration settings}.
|
||||
*
|
||||
* @param tokenSettingsConsumer a {@link Consumer} of the token configuration settings
|
||||
* @param tokenSettings the token configuration settings
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public Builder tokenSettings(Consumer<TokenSettings> tokenSettingsConsumer) {
|
||||
tokenSettingsConsumer.accept(this.tokenSettings);
|
||||
public Builder tokenSettings(TokenSettings tokenSettings) {
|
||||
this.tokenSettings = tokenSettings;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -506,8 +504,10 @@ public class RegisteredClient implements Serializable {
|
||||
new HashSet<>(this.redirectUris));
|
||||
registeredClient.scopes = Collections.unmodifiableSet(
|
||||
new HashSet<>(this.scopes));
|
||||
registeredClient.clientSettings = new ClientSettings(this.clientSettings.settings());
|
||||
registeredClient.tokenSettings = new TokenSettings(this.tokenSettings.settings());
|
||||
registeredClient.clientSettings = this.clientSettings != null ?
|
||||
this.clientSettings : ClientSettings.builder().build();
|
||||
registeredClient.tokenSettings = this.tokenSettings != null ?
|
||||
this.tokenSettings : TokenSettings.builder().build();
|
||||
|
||||
return registeredClient;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2020-2021 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.config;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.security.oauth2.core.Version;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base implementation for configuration settings.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.2
|
||||
*/
|
||||
public abstract class AbstractSettings implements Serializable {
|
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
|
||||
private final Map<String, Object> settings;
|
||||
|
||||
protected AbstractSettings(Map<String, Object> settings) {
|
||||
Assert.notEmpty(settings, "settings cannot be empty");
|
||||
this.settings = Collections.unmodifiableMap(new HashMap<>(settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a configuration setting.
|
||||
*
|
||||
* @param name the name of the setting
|
||||
* @param <T> the type of the setting
|
||||
* @return the value of the setting, or {@code null} if not available
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getSetting(String name) {
|
||||
Assert.hasText(name, "name cannot be empty");
|
||||
return (T) getSettings().get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Map} of the configuration settings.
|
||||
*
|
||||
* @return a {@code Map} of the configuration settings
|
||||
*/
|
||||
public Map<String, Object> getSettings() {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AbstractSettings that = (AbstractSettings) obj;
|
||||
return this.settings.equals(that.settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AbstractSettings {" +
|
||||
"settings=" + this.settings +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for subclasses of {@link AbstractSettings}.
|
||||
*/
|
||||
protected static abstract class AbstractBuilder<T extends AbstractSettings, B extends AbstractBuilder<T, B>> {
|
||||
private final Map<String, Object> settings = new HashMap<>();
|
||||
|
||||
protected AbstractBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a configuration setting.
|
||||
*
|
||||
* @param name the name of the setting
|
||||
* @param value the value of the setting
|
||||
* @return the {@link AbstractBuilder} for further configuration
|
||||
*/
|
||||
public B setting(String name, Object value) {
|
||||
Assert.hasText(name, "name cannot be empty");
|
||||
Assert.notNull(value, "value cannot be null");
|
||||
getSettings().put(name, value);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code Consumer} of the configuration settings {@code Map}
|
||||
* allowing the ability to add, replace, or remove.
|
||||
*
|
||||
* @param settingsConsumer a {@link Consumer} of the configuration settings {@code Map}
|
||||
* @return the {@link AbstractBuilder} for further configuration
|
||||
*/
|
||||
public B settings(Consumer<Map<String, Object>> settingsConsumer) {
|
||||
settingsConsumer.accept(getSettings());
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public abstract T build();
|
||||
|
||||
protected final Map<String, Object> getSettings() {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected final B getThis() {
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,34 +15,23 @@
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A facility for client configuration settings.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.2
|
||||
* @see Settings
|
||||
* @see AbstractSettings
|
||||
*/
|
||||
public class ClientSettings extends Settings {
|
||||
public final class ClientSettings extends AbstractSettings {
|
||||
private static final String CLIENT_SETTING_BASE = "setting.client.";
|
||||
public static final String REQUIRE_PROOF_KEY = CLIENT_SETTING_BASE.concat("require-proof-key");
|
||||
public static final String REQUIRE_AUTHORIZATION_CONSENT = CLIENT_SETTING_BASE.concat("require-authorization-consent");
|
||||
|
||||
/**
|
||||
* Constructs a {@code ClientSettings}.
|
||||
*/
|
||||
public ClientSettings() {
|
||||
this(defaultSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code ClientSettings} using the provided parameters.
|
||||
*
|
||||
* @param settings the initial settings
|
||||
*/
|
||||
public ClientSettings(Map<String, Object> settings) {
|
||||
private ClientSettings(Map<String, Object> settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@@ -52,20 +41,8 @@ public class ClientSettings extends Settings {
|
||||
*
|
||||
* @return {@code true} if the client is required to provide a proof key challenge and verifier, {@code false} otherwise
|
||||
*/
|
||||
public boolean requireProofKey() {
|
||||
return setting(REQUIRE_PROOF_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} if the client is required to provide a proof key challenge and verifier
|
||||
* when performing the Authorization Code Grant flow.
|
||||
*
|
||||
* @param requireProofKey {@code true} if the client is required to provide a proof key challenge and verifier, {@code false} otherwise
|
||||
* @return the {@link ClientSettings}
|
||||
*/
|
||||
public ClientSettings requireProofKey(boolean requireProofKey) {
|
||||
setting(REQUIRE_PROOF_KEY, requireProofKey);
|
||||
return this;
|
||||
public boolean isRequireProofKey() {
|
||||
return getSetting(REQUIRE_PROOF_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,26 +51,73 @@ public class ClientSettings extends Settings {
|
||||
*
|
||||
* @return {@code true} if authorization consent is required when the client requests access, {@code false} otherwise
|
||||
*/
|
||||
public boolean requireAuthorizationConsent() {
|
||||
return setting(REQUIRE_AUTHORIZATION_CONSENT);
|
||||
public boolean isRequireAuthorizationConsent() {
|
||||
return getSetting(REQUIRE_AUTHORIZATION_CONSENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} if authorization consent is required when the client requests access.
|
||||
* This applies to all interactive flows (e.g. {@code authorization_code} and {@code device_code}).
|
||||
* Constructs a new {@link Builder} with the default settings.
|
||||
*
|
||||
* @param requireAuthorizationConsent {@code true} if authorization consent is required when the client requests access, {@code false} otherwise
|
||||
* @return the {@link ClientSettings}
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public ClientSettings requireAuthorizationConsent(boolean requireAuthorizationConsent) {
|
||||
setting(REQUIRE_AUTHORIZATION_CONSENT, requireAuthorizationConsent);
|
||||
return this;
|
||||
public static Builder builder() {
|
||||
return new Builder()
|
||||
.requireProofKey(false)
|
||||
.requireAuthorizationConsent(false);
|
||||
}
|
||||
|
||||
protected static Map<String, Object> defaultSettings() {
|
||||
Map<String, Object> settings = new HashMap<>();
|
||||
settings.put(REQUIRE_PROOF_KEY, false);
|
||||
settings.put(REQUIRE_AUTHORIZATION_CONSENT, false);
|
||||
return settings;
|
||||
/**
|
||||
* Constructs a new {@link Builder} with the provided settings.
|
||||
*
|
||||
* @param settings the settings to initialize the builder
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public static Builder withSettings(Map<String, Object> settings) {
|
||||
Assert.notEmpty(settings, "settings cannot be empty");
|
||||
return new Builder()
|
||||
.settings(s -> s.putAll(settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for {@link ClientSettings}.
|
||||
*/
|
||||
public static class Builder extends AbstractBuilder<ClientSettings, Builder> {
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} if the client is required to provide a proof key challenge and verifier
|
||||
* when performing the Authorization Code Grant flow.
|
||||
*
|
||||
* @param requireProofKey {@code true} if the client is required to provide a proof key challenge and verifier, {@code false} otherwise
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder requireProofKey(boolean requireProofKey) {
|
||||
return setting(REQUIRE_PROOF_KEY, requireProofKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} if authorization consent is required when the client requests access.
|
||||
* This applies to all interactive flows (e.g. {@code authorization_code} and {@code device_code}).
|
||||
*
|
||||
* @param requireAuthorizationConsent {@code true} if authorization consent is required when the client requests access, {@code false} otherwise
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder requireAuthorizationConsent(boolean requireAuthorizationConsent) {
|
||||
return setting(REQUIRE_AUTHORIZATION_CONSENT, requireAuthorizationConsent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link ClientSettings}.
|
||||
*
|
||||
* @return the {@link ClientSettings}
|
||||
*/
|
||||
@Override
|
||||
public ClientSettings build() {
|
||||
return new ClientSettings(getSettings());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,17 +15,19 @@
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A facility for provider configuration settings.
|
||||
*
|
||||
* @author Daniel Garnier-Moiroux
|
||||
* @author Joe Grandja
|
||||
* @since 0.1.0
|
||||
* @see Settings
|
||||
* @see AbstractSettings
|
||||
*/
|
||||
public class ProviderSettings extends Settings {
|
||||
public final class ProviderSettings extends AbstractSettings {
|
||||
private static final String PROVIDER_SETTING_BASE = "setting.provider.";
|
||||
public static final String ISSUER = PROVIDER_SETTING_BASE.concat("issuer");
|
||||
public static final String AUTHORIZATION_ENDPOINT = PROVIDER_SETTING_BASE.concat("authorization-endpoint");
|
||||
@@ -35,19 +37,7 @@ public class ProviderSettings extends Settings {
|
||||
public static final String TOKEN_INTROSPECTION_ENDPOINT = PROVIDER_SETTING_BASE.concat("token-introspection-endpoint");
|
||||
public static final String OIDC_CLIENT_REGISTRATION_ENDPOINT = PROVIDER_SETTING_BASE.concat("oidc-client-registration-endpoint");
|
||||
|
||||
/**
|
||||
* Constructs a {@code ProviderSettings}.
|
||||
*/
|
||||
public ProviderSettings() {
|
||||
this(defaultSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code ProviderSettings} using the provided parameters.
|
||||
*
|
||||
* @param settings the initial settings
|
||||
*/
|
||||
public ProviderSettings(Map<String, Object> settings) {
|
||||
private ProviderSettings(Map<String, Object> settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@@ -56,18 +46,8 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the URL of the Provider's Issuer Identifier
|
||||
*/
|
||||
public String issuer() {
|
||||
return setting(ISSUER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL the Provider uses as its Issuer Identifier.
|
||||
*
|
||||
* @param issuer the URL the Provider uses as its Issuer Identifier.
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
*/
|
||||
public ProviderSettings issuer(String issuer) {
|
||||
return setting(ISSUER, issuer);
|
||||
public String getIssuer() {
|
||||
return getSetting(ISSUER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,18 +55,8 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the Authorization endpoint
|
||||
*/
|
||||
public String authorizationEndpoint() {
|
||||
return setting(AUTHORIZATION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Authorization endpoint.
|
||||
*
|
||||
* @param authorizationEndpoint the Authorization endpoint
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
*/
|
||||
public ProviderSettings authorizationEndpoint(String authorizationEndpoint) {
|
||||
return setting(AUTHORIZATION_ENDPOINT, authorizationEndpoint);
|
||||
public String getAuthorizationEndpoint() {
|
||||
return getSetting(AUTHORIZATION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,18 +64,8 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the Token endpoint
|
||||
*/
|
||||
public String tokenEndpoint() {
|
||||
return setting(TOKEN_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Token endpoint.
|
||||
*
|
||||
* @param tokenEndpoint the Token endpoint
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
*/
|
||||
public ProviderSettings tokenEndpoint(String tokenEndpoint) {
|
||||
return setting(TOKEN_ENDPOINT, tokenEndpoint);
|
||||
public String getTokenEndpoint() {
|
||||
return getSetting(TOKEN_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,18 +73,8 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the JWK Set endpoint
|
||||
*/
|
||||
public String jwkSetEndpoint() {
|
||||
return setting(JWK_SET_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's JWK Set endpoint.
|
||||
*
|
||||
* @param jwkSetEndpoint the JWK Set endpoint
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
*/
|
||||
public ProviderSettings jwkSetEndpoint(String jwkSetEndpoint) {
|
||||
return setting(JWK_SET_ENDPOINT, jwkSetEndpoint);
|
||||
public String getJwkSetEndpoint() {
|
||||
return getSetting(JWK_SET_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,18 +82,8 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the Token Revocation endpoint
|
||||
*/
|
||||
public String tokenRevocationEndpoint() {
|
||||
return setting(TOKEN_REVOCATION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Token Revocation endpoint.
|
||||
*
|
||||
* @param tokenRevocationEndpoint the Token Revocation endpoint
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
*/
|
||||
public ProviderSettings tokenRevocationEndpoint(String tokenRevocationEndpoint) {
|
||||
return setting(TOKEN_REVOCATION_ENDPOINT, tokenRevocationEndpoint);
|
||||
public String getTokenRevocationEndpoint() {
|
||||
return getSetting(TOKEN_REVOCATION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,18 +91,8 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the Token Introspection endpoint
|
||||
*/
|
||||
public String tokenIntrospectionEndpoint() {
|
||||
return setting(TOKEN_INTROSPECTION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Token Introspection endpoint.
|
||||
*
|
||||
* @param tokenIntrospectionEndpoint the Token Introspection endpoint
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
*/
|
||||
public ProviderSettings tokenIntrospectionEndpoint(String tokenIntrospectionEndpoint) {
|
||||
return setting(TOKEN_INTROSPECTION_ENDPOINT, tokenIntrospectionEndpoint);
|
||||
public String getTokenIntrospectionEndpoint() {
|
||||
return getSetting(TOKEN_INTROSPECTION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,28 +100,125 @@ public class ProviderSettings extends Settings {
|
||||
*
|
||||
* @return the OpenID Connect 1.0 Client Registration endpoint
|
||||
*/
|
||||
public String oidcClientRegistrationEndpoint() {
|
||||
return setting(OIDC_CLIENT_REGISTRATION_ENDPOINT);
|
||||
public String getOidcClientRegistrationEndpoint() {
|
||||
return getSetting(OIDC_CLIENT_REGISTRATION_ENDPOINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OpenID Connect 1.0 Client Registration endpoint.
|
||||
* Constructs a new {@link Builder} with the default settings.
|
||||
*
|
||||
* @param oidcClientRegistrationEndpoint the OpenID Connect 1.0 Client Registration endpoint
|
||||
* @return the {@link ProviderSettings} for further configuration
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public ProviderSettings oidcClientRegistrationEndpoint(String oidcClientRegistrationEndpoint) {
|
||||
return setting(OIDC_CLIENT_REGISTRATION_ENDPOINT, oidcClientRegistrationEndpoint);
|
||||
public static Builder builder() {
|
||||
return new Builder()
|
||||
.authorizationEndpoint("/oauth2/authorize")
|
||||
.tokenEndpoint("/oauth2/token")
|
||||
.jwkSetEndpoint("/oauth2/jwks")
|
||||
.tokenRevocationEndpoint("/oauth2/revoke")
|
||||
.tokenIntrospectionEndpoint("/oauth2/introspect")
|
||||
.oidcClientRegistrationEndpoint("/connect/register");
|
||||
}
|
||||
|
||||
protected static Map<String, Object> defaultSettings() {
|
||||
Map<String, Object> settings = new HashMap<>();
|
||||
settings.put(AUTHORIZATION_ENDPOINT, "/oauth2/authorize");
|
||||
settings.put(TOKEN_ENDPOINT, "/oauth2/token");
|
||||
settings.put(JWK_SET_ENDPOINT, "/oauth2/jwks");
|
||||
settings.put(TOKEN_REVOCATION_ENDPOINT, "/oauth2/revoke");
|
||||
settings.put(TOKEN_INTROSPECTION_ENDPOINT, "/oauth2/introspect");
|
||||
settings.put(OIDC_CLIENT_REGISTRATION_ENDPOINT, "/connect/register");
|
||||
return settings;
|
||||
/**
|
||||
* Constructs a new {@link Builder} with the provided settings.
|
||||
*
|
||||
* @param settings the settings to initialize the builder
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public static Builder withSettings(Map<String, Object> settings) {
|
||||
Assert.notEmpty(settings, "settings cannot be empty");
|
||||
return new Builder()
|
||||
.settings(s -> s.putAll(settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for {@link ProviderSettings}.
|
||||
*/
|
||||
public static class Builder extends AbstractBuilder<ProviderSettings, Builder> {
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL the Provider uses as its Issuer Identifier.
|
||||
*
|
||||
* @param issuer the URL the Provider uses as its Issuer Identifier.
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder issuer(String issuer) {
|
||||
return setting(ISSUER, issuer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Authorization endpoint.
|
||||
*
|
||||
* @param authorizationEndpoint the Authorization endpoint
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder authorizationEndpoint(String authorizationEndpoint) {
|
||||
return setting(AUTHORIZATION_ENDPOINT, authorizationEndpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Token endpoint.
|
||||
*
|
||||
* @param tokenEndpoint the Token endpoint
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder tokenEndpoint(String tokenEndpoint) {
|
||||
return setting(TOKEN_ENDPOINT, tokenEndpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's JWK Set endpoint.
|
||||
*
|
||||
* @param jwkSetEndpoint the JWK Set endpoint
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder jwkSetEndpoint(String jwkSetEndpoint) {
|
||||
return setting(JWK_SET_ENDPOINT, jwkSetEndpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Token Revocation endpoint.
|
||||
*
|
||||
* @param tokenRevocationEndpoint the Token Revocation endpoint
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder tokenRevocationEndpoint(String tokenRevocationEndpoint) {
|
||||
return setting(TOKEN_REVOCATION_ENDPOINT, tokenRevocationEndpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OAuth 2.0 Token Introspection endpoint.
|
||||
*
|
||||
* @param tokenIntrospectionEndpoint the Token Introspection endpoint
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder tokenIntrospectionEndpoint(String tokenIntrospectionEndpoint) {
|
||||
return setting(TOKEN_INTROSPECTION_ENDPOINT, tokenIntrospectionEndpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Provider's OpenID Connect 1.0 Client Registration endpoint.
|
||||
*
|
||||
* @param oidcClientRegistrationEndpoint the OpenID Connect 1.0 Client Registration endpoint
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder oidcClientRegistrationEndpoint(String oidcClientRegistrationEndpoint) {
|
||||
return setting(OIDC_CLIENT_REGISTRATION_ENDPOINT, oidcClientRegistrationEndpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link ProviderSettings}.
|
||||
*
|
||||
* @return the {@link ProviderSettings}
|
||||
*/
|
||||
@Override
|
||||
public ProviderSettings build() {
|
||||
return new ProviderSettings(getSettings());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.config;
|
||||
|
||||
import org.springframework.security.oauth2.core.Version;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A facility for configuration settings.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.2
|
||||
*/
|
||||
public class Settings implements Serializable {
|
||||
private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
|
||||
private final Map<String, Object> settings;
|
||||
|
||||
/**
|
||||
* Constructs a {@code Settings}.
|
||||
*/
|
||||
public Settings() {
|
||||
this.settings = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code Settings} using the provided parameters.
|
||||
*
|
||||
* @param settings the initial settings
|
||||
*/
|
||||
public Settings(Map<String, Object> settings) {
|
||||
Assert.notNull(settings, "settings cannot be null");
|
||||
this.settings = new HashMap<>(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a configuration setting.
|
||||
*
|
||||
* @param name the name of the setting
|
||||
* @param <T> the type of the setting
|
||||
* @return the value of the setting, or {@code null} if not available
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T setting(String name) {
|
||||
Assert.hasText(name, "name cannot be empty");
|
||||
return (T) this.settings.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a configuration setting.
|
||||
*
|
||||
* @param name the name of the setting
|
||||
* @param value the value of the setting
|
||||
* @param <T> the type of the {@link Settings}
|
||||
* @return the {@link Settings}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Settings> T setting(String name, Object value) {
|
||||
Assert.hasText(name, "name cannot be empty");
|
||||
Assert.notNull(value, "value cannot be null");
|
||||
this.settings.put(name, value);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Map} of the configuration settings.
|
||||
*
|
||||
* @return a {@code Map} of the configuration settings
|
||||
*/
|
||||
public Map<String, Object> settings() {
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code Consumer} of the configuration settings {@code Map}
|
||||
* allowing the ability to add, replace, or remove.
|
||||
*
|
||||
* @param settingsConsumer a {@link Consumer} of the configuration settings {@code Map}
|
||||
* @param <T> the type of the {@link Settings}
|
||||
* @return the {@link Settings}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Settings> T settings(Consumer<Map<String, Object>> settingsConsumer) {
|
||||
settingsConsumer.accept(this.settings);
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.security.oauth2.server.authorization.config;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
||||
@@ -28,28 +27,16 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @since 0.0.2
|
||||
* @see Settings
|
||||
* @see AbstractSettings
|
||||
*/
|
||||
public class TokenSettings extends Settings {
|
||||
public final class TokenSettings extends AbstractSettings {
|
||||
private static final String TOKEN_SETTING_BASE = "setting.token.";
|
||||
public static final String ACCESS_TOKEN_TIME_TO_LIVE = TOKEN_SETTING_BASE.concat("access-token-time-to-live");
|
||||
public static final String REUSE_REFRESH_TOKENS = TOKEN_SETTING_BASE.concat("reuse-refresh-tokens");
|
||||
public static final String REFRESH_TOKEN_TIME_TO_LIVE = TOKEN_SETTING_BASE.concat("refresh-token-time-to-live");
|
||||
public static final String ID_TOKEN_SIGNATURE_ALGORITHM = TOKEN_SETTING_BASE.concat("id-token-signature-algorithm");
|
||||
|
||||
/**
|
||||
* Constructs a {@code TokenSettings}.
|
||||
*/
|
||||
public TokenSettings() {
|
||||
this(defaultSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code TokenSettings} using the provided parameters.
|
||||
*
|
||||
* @param settings the initial settings
|
||||
*/
|
||||
public TokenSettings(Map<String, Object> settings) {
|
||||
private TokenSettings(Map<String, Object> settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@@ -58,41 +45,16 @@ public class TokenSettings extends Settings {
|
||||
*
|
||||
* @return the time-to-live for an access token
|
||||
*/
|
||||
public Duration accessTokenTimeToLive() {
|
||||
return setting(ACCESS_TOKEN_TIME_TO_LIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time-to-live for an access token. Must be greater than {@code Duration.ZERO}.
|
||||
*
|
||||
* @param accessTokenTimeToLive the time-to-live for an access token
|
||||
* @return the {@link TokenSettings}
|
||||
*/
|
||||
public TokenSettings accessTokenTimeToLive(Duration accessTokenTimeToLive) {
|
||||
Assert.notNull(accessTokenTimeToLive, "accessTokenTimeToLive cannot be null");
|
||||
Assert.isTrue(accessTokenTimeToLive.getSeconds() > 0, "accessTokenTimeToLive must be greater than Duration.ZERO");
|
||||
setting(ACCESS_TOKEN_TIME_TO_LIVE, accessTokenTimeToLive);
|
||||
return this;
|
||||
public Duration getAccessTokenTimeToLive() {
|
||||
return getSetting(ACCESS_TOKEN_TIME_TO_LIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if refresh tokens are reused when returning the access token response,
|
||||
* or {@code false} if a new refresh token is issued. The default is {@code true}.
|
||||
*/
|
||||
public boolean reuseRefreshTokens() {
|
||||
return setting(REUSE_REFRESH_TOKENS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} if refresh tokens are reused when returning the access token response,
|
||||
* or {@code false} if a new refresh token is issued.
|
||||
*
|
||||
* @param reuseRefreshTokens {@code true} to reuse refresh tokens, {@code false} to issue new refresh tokens
|
||||
* @return the {@link TokenSettings}
|
||||
*/
|
||||
public TokenSettings reuseRefreshTokens(boolean reuseRefreshTokens) {
|
||||
setting(REUSE_REFRESH_TOKENS, reuseRefreshTokens);
|
||||
return this;
|
||||
public boolean isReuseRefreshTokens() {
|
||||
return getSetting(REUSE_REFRESH_TOKENS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,21 +62,8 @@ public class TokenSettings extends Settings {
|
||||
*
|
||||
* @return the time-to-live for a refresh token
|
||||
*/
|
||||
public Duration refreshTokenTimeToLive() {
|
||||
return setting(REFRESH_TOKEN_TIME_TO_LIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time-to-live for a refresh token. Must be greater than {@code Duration.ZERO}.
|
||||
*
|
||||
* @param refreshTokenTimeToLive the time-to-live for a refresh token
|
||||
* @return the {@link TokenSettings}
|
||||
*/
|
||||
public TokenSettings refreshTokenTimeToLive(Duration refreshTokenTimeToLive) {
|
||||
Assert.notNull(refreshTokenTimeToLive, "refreshTokenTimeToLive cannot be null");
|
||||
Assert.isTrue(refreshTokenTimeToLive.getSeconds() > 0, "refreshTokenTimeToLive must be greater than Duration.ZERO");
|
||||
setting(REFRESH_TOKEN_TIME_TO_LIVE, refreshTokenTimeToLive);
|
||||
return this;
|
||||
public Duration getRefreshTokenTimeToLive() {
|
||||
return getSetting(REFRESH_TOKEN_TIME_TO_LIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,29 +72,99 @@ public class TokenSettings extends Settings {
|
||||
*
|
||||
* @return the {@link SignatureAlgorithm JWS} algorithm for signing the {@link OidcIdToken ID Token}
|
||||
*/
|
||||
public SignatureAlgorithm idTokenSignatureAlgorithm() {
|
||||
return setting(ID_TOKEN_SIGNATURE_ALGORITHM);
|
||||
public SignatureAlgorithm getIdTokenSignatureAlgorithm() {
|
||||
return getSetting(ID_TOKEN_SIGNATURE_ALGORITHM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link SignatureAlgorithm JWS} algorithm for signing the {@link OidcIdToken ID Token}.
|
||||
* Constructs a new {@link Builder} with the default settings.
|
||||
*
|
||||
* @param idTokenSignatureAlgorithm the {@link SignatureAlgorithm JWS} algorithm for signing the {@link OidcIdToken ID Token}
|
||||
* @return the {@link TokenSettings}
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public TokenSettings idTokenSignatureAlgorithm(SignatureAlgorithm idTokenSignatureAlgorithm) {
|
||||
Assert.notNull(idTokenSignatureAlgorithm, "idTokenSignatureAlgorithm cannot be null");
|
||||
setting(ID_TOKEN_SIGNATURE_ALGORITHM, idTokenSignatureAlgorithm);
|
||||
return this;
|
||||
public static Builder builder() {
|
||||
return new Builder()
|
||||
.accessTokenTimeToLive(Duration.ofMinutes(5))
|
||||
.reuseRefreshTokens(true)
|
||||
.refreshTokenTimeToLive(Duration.ofMinutes(60))
|
||||
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256);
|
||||
}
|
||||
|
||||
protected static Map<String, Object> defaultSettings() {
|
||||
Map<String, Object> settings = new HashMap<>();
|
||||
settings.put(ACCESS_TOKEN_TIME_TO_LIVE, Duration.ofMinutes(5));
|
||||
settings.put(REUSE_REFRESH_TOKENS, true);
|
||||
settings.put(REFRESH_TOKEN_TIME_TO_LIVE, Duration.ofMinutes(60));
|
||||
settings.put(ID_TOKEN_SIGNATURE_ALGORITHM, SignatureAlgorithm.RS256);
|
||||
return settings;
|
||||
/**
|
||||
* Constructs a new {@link Builder} with the provided settings.
|
||||
*
|
||||
* @param settings the settings to initialize the builder
|
||||
* @return the {@link Builder}
|
||||
*/
|
||||
public static Builder withSettings(Map<String, Object> settings) {
|
||||
Assert.notEmpty(settings, "settings cannot be empty");
|
||||
return new Builder()
|
||||
.settings(s -> s.putAll(settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for {@link TokenSettings}.
|
||||
*/
|
||||
public static class Builder extends AbstractBuilder<TokenSettings, Builder> {
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time-to-live for an access token. Must be greater than {@code Duration.ZERO}.
|
||||
*
|
||||
* @param accessTokenTimeToLive the time-to-live for an access token
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder accessTokenTimeToLive(Duration accessTokenTimeToLive) {
|
||||
Assert.notNull(accessTokenTimeToLive, "accessTokenTimeToLive cannot be null");
|
||||
Assert.isTrue(accessTokenTimeToLive.getSeconds() > 0, "accessTokenTimeToLive must be greater than Duration.ZERO");
|
||||
return setting(ACCESS_TOKEN_TIME_TO_LIVE, accessTokenTimeToLive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} if refresh tokens are reused when returning the access token response,
|
||||
* or {@code false} if a new refresh token is issued.
|
||||
*
|
||||
* @param reuseRefreshTokens {@code true} to reuse refresh tokens, {@code false} to issue new refresh tokens
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder reuseRefreshTokens(boolean reuseRefreshTokens) {
|
||||
return setting(REUSE_REFRESH_TOKENS, reuseRefreshTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time-to-live for a refresh token. Must be greater than {@code Duration.ZERO}.
|
||||
*
|
||||
* @param refreshTokenTimeToLive the time-to-live for a refresh token
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder refreshTokenTimeToLive(Duration refreshTokenTimeToLive) {
|
||||
Assert.notNull(refreshTokenTimeToLive, "refreshTokenTimeToLive cannot be null");
|
||||
Assert.isTrue(refreshTokenTimeToLive.getSeconds() > 0, "refreshTokenTimeToLive must be greater than Duration.ZERO");
|
||||
return setting(REFRESH_TOKEN_TIME_TO_LIVE, refreshTokenTimeToLive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link SignatureAlgorithm JWS} algorithm for signing the {@link OidcIdToken ID Token}.
|
||||
*
|
||||
* @param idTokenSignatureAlgorithm the {@link SignatureAlgorithm JWS} algorithm for signing the {@link OidcIdToken ID Token}
|
||||
* @return the {@link Builder} for further configuration
|
||||
*/
|
||||
public Builder idTokenSignatureAlgorithm(SignatureAlgorithm idTokenSignatureAlgorithm) {
|
||||
Assert.notNull(idTokenSignatureAlgorithm, "idTokenSignatureAlgorithm cannot be null");
|
||||
return setting(ID_TOKEN_SIGNATURE_ALGORITHM, idTokenSignatureAlgorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link TokenSettings}.
|
||||
*
|
||||
* @return the {@link TokenSettings}
|
||||
*/
|
||||
@Override
|
||||
public TokenSettings build() {
|
||||
return new TokenSettings(getSettings());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
|
||||
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.AbstractOAuth2TokenAuthenticationToken;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -169,13 +171,13 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe
|
||||
}
|
||||
|
||||
builder
|
||||
.clientSettings(clientSettings ->
|
||||
clientSettings
|
||||
.requireProofKey(true)
|
||||
.requireAuthorizationConsent(true))
|
||||
.tokenSettings(tokenSettings ->
|
||||
tokenSettings
|
||||
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256));
|
||||
.clientSettings(ClientSettings.builder()
|
||||
.requireProofKey(true)
|
||||
.requireAuthorizationConsent(true)
|
||||
.build())
|
||||
.tokenSettings(TokenSettings.builder()
|
||||
.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
|
||||
.build());
|
||||
|
||||
return builder.build();
|
||||
// @formatter:on
|
||||
@@ -207,7 +209,7 @@ public final class OidcClientRegistrationAuthenticationProvider implements Authe
|
||||
|
||||
builder
|
||||
.tokenEndpointAuthenticationMethod(registeredClient.getClientAuthenticationMethods().iterator().next().getValue())
|
||||
.idTokenSignedResponseAlgorithm(registeredClient.getTokenSettings().idTokenSignatureAlgorithm().getName());
|
||||
.idTokenSignedResponseAlgorithm(registeredClient.getTokenSettings().getIdTokenSignatureAlgorithm().getName());
|
||||
|
||||
return builder.build();
|
||||
// @formatter:on
|
||||
|
||||
@@ -77,12 +77,12 @@ public final class OidcProviderConfigurationEndpointFilter extends OncePerReques
|
||||
}
|
||||
|
||||
OidcProviderConfiguration providerConfiguration = OidcProviderConfiguration.builder()
|
||||
.issuer(this.providerSettings.issuer())
|
||||
.authorizationEndpoint(asUrl(this.providerSettings.issuer(), this.providerSettings.authorizationEndpoint()))
|
||||
.tokenEndpoint(asUrl(this.providerSettings.issuer(), this.providerSettings.tokenEndpoint()))
|
||||
.issuer(this.providerSettings.getIssuer())
|
||||
.authorizationEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getAuthorizationEndpoint()))
|
||||
.tokenEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getTokenEndpoint()))
|
||||
.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
|
||||
.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST.getValue())
|
||||
.jwkSetUrl(asUrl(this.providerSettings.issuer(), this.providerSettings.jwkSetEndpoint()))
|
||||
.jwkSetUrl(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getJwkSetEndpoint()))
|
||||
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
|
||||
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
|
||||
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
|
||||
|
||||
@@ -78,18 +78,18 @@ public final class OAuth2AuthorizationServerMetadataEndpointFilter extends OnceP
|
||||
}
|
||||
|
||||
OAuth2AuthorizationServerMetadata authorizationServerMetadata = OAuth2AuthorizationServerMetadata.builder()
|
||||
.issuer(this.providerSettings.issuer())
|
||||
.authorizationEndpoint(asUrl(this.providerSettings.issuer(), this.providerSettings.authorizationEndpoint()))
|
||||
.tokenEndpoint(asUrl(this.providerSettings.issuer(), this.providerSettings.tokenEndpoint()))
|
||||
.issuer(this.providerSettings.getIssuer())
|
||||
.authorizationEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getAuthorizationEndpoint()))
|
||||
.tokenEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getTokenEndpoint()))
|
||||
.tokenEndpointAuthenticationMethods(clientAuthenticationMethods())
|
||||
.jwkSetUrl(asUrl(this.providerSettings.issuer(), this.providerSettings.jwkSetEndpoint()))
|
||||
.jwkSetUrl(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getJwkSetEndpoint()))
|
||||
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
|
||||
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
|
||||
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
|
||||
.grantType(AuthorizationGrantType.REFRESH_TOKEN.getValue())
|
||||
.tokenRevocationEndpoint(asUrl(this.providerSettings.issuer(), this.providerSettings.tokenRevocationEndpoint()))
|
||||
.tokenRevocationEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getTokenRevocationEndpoint()))
|
||||
.tokenRevocationEndpointAuthenticationMethods(clientAuthenticationMethods())
|
||||
.tokenIntrospectionEndpoint(asUrl(this.providerSettings.issuer(), this.providerSettings.tokenIntrospectionEndpoint()))
|
||||
.tokenIntrospectionEndpoint(asUrl(this.providerSettings.getIssuer(), this.providerSettings.getTokenIntrospectionEndpoint()))
|
||||
.tokenIntrospectionEndpointAuthenticationMethods(clientAuthenticationMethods())
|
||||
.codeChallengeMethod("plain")
|
||||
.codeChallengeMethod("S256")
|
||||
|
||||
@@ -76,7 +76,7 @@ public class JwkSetTests {
|
||||
public static void init() {
|
||||
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
|
||||
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
providerSettings = new ProviderSettings().jwkSetEndpoint("/test/jwks");
|
||||
providerSettings = ProviderSettings.builder().jwkSetEndpoint("/test/jwks").build();
|
||||
db = new EmbeddedDatabaseBuilder()
|
||||
.generateUniqueName(true)
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
@@ -108,7 +108,7 @@ public class JwkSetTests {
|
||||
public void requestWhenJwkSetCustomEndpointThenReturnKeys() throws Exception {
|
||||
this.spring.register(AuthorizationServerConfigurationCustomEndpoints.class).autowire();
|
||||
|
||||
assertJwkSetRequestThenReturnKeys(providerSettings.jwkSetEndpoint());
|
||||
assertJwkSetRequestThenReturnKeys(providerSettings.getJwkSetEndpoint());
|
||||
}
|
||||
|
||||
private void assertJwkSetRequestThenReturnKeys(String jwkSetEndpointUri) throws Exception {
|
||||
|
||||
@@ -86,6 +86,7 @@ import org.springframework.security.oauth2.server.authorization.client.JdbcRegis
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.jackson2.TestingAuthenticationTokenMixin;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
@@ -167,9 +168,10 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
|
||||
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
jwtEncoder = new NimbusJwsEncoder(jwkSource);
|
||||
providerSettings = new ProviderSettings()
|
||||
providerSettings = ProviderSettings.builder()
|
||||
.authorizationEndpoint("/test/authorize")
|
||||
.tokenEndpoint("/test/token");
|
||||
.tokenEndpoint("/test/token")
|
||||
.build();
|
||||
authorizationRequestConverter = mock(AuthenticationConverter.class);
|
||||
authorizationRequestAuthenticationProvider = mock(AuthenticationProvider.class);
|
||||
authorizationResponseHandler = mock(AuthenticationSuccessHandler.class);
|
||||
@@ -232,7 +234,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
public void requestWhenAuthorizationRequestCustomEndpointThenRedirectToClient() throws Exception {
|
||||
this.spring.register(AuthorizationServerConfigurationCustomEndpoints.class).autowire();
|
||||
|
||||
assertAuthorizationRequestRedirectsToClient(providerSettings.authorizationEndpoint());
|
||||
assertAuthorizationRequestRedirectsToClient(providerSettings.getAuthorizationEndpoint());
|
||||
}
|
||||
|
||||
private void assertAuthorizationRequestRedirectsToClient(String authorizationEndpointUri) throws Exception {
|
||||
@@ -287,7 +289,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
this.authorizationService.save(authorization);
|
||||
|
||||
assertTokenRequestReturnsAccessTokenResponse(
|
||||
registeredClient, authorization, providerSettings.tokenEndpoint());
|
||||
registeredClient, authorization, providerSettings.getTokenEndpoint());
|
||||
}
|
||||
|
||||
private OAuth2AccessTokenResponse assertTokenRequestReturnsAccessTokenResponse(RegisteredClient registeredClient,
|
||||
@@ -389,7 +391,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
scopes.add("message.read");
|
||||
scopes.add("message.write");
|
||||
})
|
||||
.clientSettings(settings -> settings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
this.registeredClientRepository.save(registeredClient);
|
||||
|
||||
@@ -416,7 +418,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
scopes.add("message.read");
|
||||
scopes.add("message.write");
|
||||
})
|
||||
.clientSettings(settings -> settings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
this.registeredClientRepository.save(registeredClient);
|
||||
|
||||
@@ -464,7 +466,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
||||
scopes.add("message.read");
|
||||
scopes.add("message.write");
|
||||
})
|
||||
.clientSettings(settings -> settings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
this.registeredClientRepository.save(registeredClient);
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ public class OAuth2AuthorizationServerMetadataTests {
|
||||
|
||||
@Bean
|
||||
ProviderSettings providerSettings() {
|
||||
return new ProviderSettings().issuer(issuerUrl);
|
||||
return ProviderSettings.builder().issuer(issuerUrl).build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public class OAuth2TokenIntrospectionTests {
|
||||
public static void init() {
|
||||
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
|
||||
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
providerSettings = new ProviderSettings().tokenIntrospectionEndpoint("/test/introspect");
|
||||
providerSettings = ProviderSettings.builder().tokenIntrospectionEndpoint("/test/introspect").build();
|
||||
db = new EmbeddedDatabaseBuilder()
|
||||
.generateUniqueName(true)
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
@@ -152,7 +152,7 @@ public class OAuth2TokenIntrospectionTests {
|
||||
this.authorizationService.save(authorization);
|
||||
|
||||
// @formatter:off
|
||||
MvcResult mvcResult = this.mvc.perform(post(providerSettings.tokenIntrospectionEndpoint())
|
||||
MvcResult mvcResult = this.mvc.perform(post(providerSettings.getTokenIntrospectionEndpoint())
|
||||
.params(getTokenIntrospectionRequestParameters(accessToken, OAuth2TokenType.ACCESS_TOKEN))
|
||||
.with(httpBasic(introspectRegisteredClient.getClientId(), introspectRegisteredClient.getClientSecret())))
|
||||
.andExpect(status().isOk())
|
||||
@@ -192,7 +192,7 @@ public class OAuth2TokenIntrospectionTests {
|
||||
this.authorizationService.save(authorization);
|
||||
|
||||
// @formatter:off
|
||||
MvcResult mvcResult = this.mvc.perform(post(providerSettings.tokenIntrospectionEndpoint())
|
||||
MvcResult mvcResult = this.mvc.perform(post(providerSettings.getTokenIntrospectionEndpoint())
|
||||
.params(getTokenIntrospectionRequestParameters(refreshToken, OAuth2TokenType.REFRESH_TOKEN))
|
||||
.with(httpBasic(introspectRegisteredClient.getClientId(), introspectRegisteredClient.getClientSecret())))
|
||||
.andExpect(status().isOk())
|
||||
|
||||
@@ -97,7 +97,7 @@ public class OAuth2TokenRevocationTests {
|
||||
public static void init() {
|
||||
JWKSet jwkSet = new JWKSet(TestJwks.DEFAULT_RSA_JWK);
|
||||
jwkSource = (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
|
||||
providerSettings = new ProviderSettings().tokenRevocationEndpoint("/test/revoke");
|
||||
providerSettings = ProviderSettings.builder().tokenRevocationEndpoint("/test/revoke").build();
|
||||
db = new EmbeddedDatabaseBuilder()
|
||||
.generateUniqueName(true)
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
@@ -154,7 +154,7 @@ public class OAuth2TokenRevocationTests {
|
||||
public void requestWhenRevokeAccessTokenCustomEndpointThenRevoked() throws Exception {
|
||||
this.spring.register(AuthorizationServerConfigurationCustomEndpoints.class).autowire();
|
||||
|
||||
assertRevokeAccessTokenThenRevoked(providerSettings.tokenRevocationEndpoint());
|
||||
assertRevokeAccessTokenThenRevoked(providerSettings.getTokenRevocationEndpoint());
|
||||
}
|
||||
|
||||
private void assertRevokeAccessTokenThenRevoked(String tokenRevocationEndpointUri) throws Exception {
|
||||
|
||||
@@ -333,7 +333,7 @@ public class OidcTests {
|
||||
|
||||
@Bean
|
||||
ProviderSettings providerSettings() {
|
||||
return new ProviderSettings().issuer(ISSUER_URL);
|
||||
return ProviderSettings.builder().issuer(ISSUER_URL).build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ public class OidcTests {
|
||||
|
||||
@Bean
|
||||
ProviderSettings providerSettings() {
|
||||
return new ProviderSettings().issuer("urn:example");
|
||||
return ProviderSettings.builder().issuer("urn:example").build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ public class OidcTests {
|
||||
|
||||
@Bean
|
||||
ProviderSettings providerSettings() {
|
||||
return new ProviderSettings().issuer("https://not a valid uri");
|
||||
return ProviderSettings.builder().issuer("https://not a valid uri").build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2TokenCusto
|
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -377,8 +378,10 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||
Duration accessTokenTTL = Duration.ofHours(2);
|
||||
Duration refreshTokenTTL = Duration.ofDays(1);
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.tokenSettings(tokenSettings ->
|
||||
tokenSettings.accessTokenTimeToLive(accessTokenTTL).refreshTokenTimeToLive(refreshTokenTTL))
|
||||
.tokenSettings(TokenSettings.builder()
|
||||
.accessTokenTimeToLive(accessTokenTTL)
|
||||
.refreshTokenTimeToLive(refreshTokenTTL)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.springframework.security.oauth2.server.authorization.TestOAuth2Author
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -309,7 +310,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
|
||||
@Test
|
||||
public void authenticateWhenPkceRequiredAndMissingCodeChallengeThenThrowOAuth2AuthorizationCodeRequestAuthenticationException() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.clientSettings(clientSettings -> clientSettings.requireProofKey(true))
|
||||
.clientSettings(ClientSettings.builder().requireProofKey(true).build())
|
||||
.build();
|
||||
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
|
||||
.thenReturn(registeredClient);
|
||||
@@ -365,7 +366,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
|
||||
@Test
|
||||
public void authenticateWhenRequireAuthorizationConsentThenReturnAuthorizationConsent() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.clientSettings(clientSettings -> clientSettings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
|
||||
.thenReturn(registeredClient);
|
||||
@@ -412,7 +413,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
|
||||
@Test
|
||||
public void authenticateWhenRequireAuthorizationConsentAndOnlyOpenidScopeRequestedThenAuthorizationConsentNotRequired() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.clientSettings(clientSettings -> clientSettings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.scopes(scopes -> {
|
||||
scopes.clear();
|
||||
scopes.add(OidcScopes.OPENID);
|
||||
@@ -434,7 +435,7 @@ public class OAuth2AuthorizationCodeRequestAuthenticationProviderTests {
|
||||
@Test
|
||||
public void authenticateWhenRequireAuthorizationConsentAndAllPreviouslyApprovedThenAuthorizationConsentNotRequired() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.clientSettings(clientSettings -> clientSettings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
|
||||
.thenReturn(registeredClient);
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.security.oauth2.server.authorization.TestOAuth2Author
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -209,7 +210,7 @@ public class OAuth2ClientAuthenticationProviderTests {
|
||||
@Test
|
||||
public void authenticateWhenPkceAndRequireProofKeyAndMissingCodeChallengeThenThrowOAuth2AuthenticationException() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.clientSettings(clientSettings -> clientSettings.requireProofKey(true))
|
||||
.clientSettings(ClientSettings.builder().requireProofKey(true).build())
|
||||
.build();
|
||||
when(this.registeredClientRepository.findByClientId(eq(registeredClient.getClientId())))
|
||||
.thenReturn(registeredClient);
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2TokenCusto
|
||||
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
|
||||
@@ -233,7 +234,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
|
||||
@Test
|
||||
public void authenticateWhenReuseRefreshTokensFalseThenReturnNewRefreshToken() {
|
||||
RegisteredClient registeredClient = TestRegisteredClients.registeredClient()
|
||||
.tokenSettings(tokenSettings -> tokenSettings.reuseRefreshTokens(false))
|
||||
.tokenSettings(TokenSettings.builder().reuseRefreshTokens(false).build())
|
||||
.build();
|
||||
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient).build();
|
||||
when(this.authorizationService.findByToken(
|
||||
|
||||
@@ -42,6 +42,8 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.security.jackson2.SecurityJackson2Modules;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.TokenSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -322,12 +324,10 @@ public class JdbcRegisteredClientRepositoryTests {
|
||||
// @formatter:on
|
||||
|
||||
Map<String, Object> clientSettingsMap = parseMap(rs.getString("clientSettings"));
|
||||
builder.clientSettings(clientSettings ->
|
||||
clientSettings.settings().putAll(clientSettingsMap));
|
||||
builder.clientSettings(ClientSettings.withSettings(clientSettingsMap).build());
|
||||
|
||||
Map<String, Object> tokenSettingsMap = parseMap(rs.getString("tokenSettings"));
|
||||
builder.tokenSettings(tokenSettings ->
|
||||
tokenSettings.settings().putAll(tokenSettingsMap));
|
||||
builder.tokenSettings(TokenSettings.withSettings(tokenSettingsMap).build());
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -347,9 +347,9 @@ public class RegisteredClientTests {
|
||||
assertThat(registration.getRedirectUris()).isNotSameAs(updated.getRedirectUris());
|
||||
assertThat(registration.getScopes()).isEqualTo(updated.getScopes());
|
||||
assertThat(registration.getScopes()).isNotSameAs(updated.getScopes());
|
||||
assertThat(registration.getClientSettings().settings()).isEqualTo(updated.getClientSettings().settings());
|
||||
assertThat(registration.getClientSettings()).isEqualTo(updated.getClientSettings());
|
||||
assertThat(registration.getClientSettings()).isNotSameAs(updated.getClientSettings());
|
||||
assertThat(registration.getTokenSettings().settings()).isEqualTo(updated.getTokenSettings().settings());
|
||||
assertThat(registration.getTokenSettings()).isEqualTo(updated.getTokenSettings());
|
||||
assertThat(registration.getTokenSettings()).isNotSameAs(updated.getTokenSettings());
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.time.temporal.ChronoUnit;
|
||||
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
|
||||
/**
|
||||
* @author Anoop Garlapati
|
||||
@@ -61,6 +62,6 @@ public class TestRegisteredClients {
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
|
||||
.redirectUri("https://example.com")
|
||||
.scope("scope1")
|
||||
.clientSettings(clientSettings -> clientSettings.requireProofKey(true));
|
||||
.clientSettings(ClientSettings.builder().requireProofKey(true).build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.security.oauth2.server.authorization.config;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
/**
|
||||
* Tests for {@link ClientSettings}.
|
||||
@@ -28,43 +27,38 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
public class ClientSettingsTests {
|
||||
|
||||
@Test
|
||||
public void constructorWhenDefaultThenDefaultsAreSet() {
|
||||
ClientSettings clientSettings = new ClientSettings();
|
||||
assertThat(clientSettings.settings()).hasSize(2);
|
||||
assertThat(clientSettings.requireProofKey()).isFalse();
|
||||
assertThat(clientSettings.requireAuthorizationConsent()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new ClientSettings(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("settings cannot be null");
|
||||
public void buildWhenDefaultThenDefaultsAreSet() {
|
||||
ClientSettings clientSettings = ClientSettings.builder().build();
|
||||
assertThat(clientSettings.getSettings()).hasSize(2);
|
||||
assertThat(clientSettings.isRequireProofKey()).isFalse();
|
||||
assertThat(clientSettings.isRequireAuthorizationConsent()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requireProofKeyWhenTrueThenSet() {
|
||||
ClientSettings clientSettings = new ClientSettings().requireProofKey(true);
|
||||
assertThat(clientSettings.requireProofKey()).isTrue();
|
||||
ClientSettings clientSettings = ClientSettings.builder()
|
||||
.requireProofKey(true)
|
||||
.build();
|
||||
assertThat(clientSettings.isRequireProofKey()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requireAuthorizationConsentWhenTrueThenSet() {
|
||||
ClientSettings clientSettings = new ClientSettings().requireAuthorizationConsent(true);
|
||||
assertThat(clientSettings.requireAuthorizationConsent()).isTrue();
|
||||
ClientSettings clientSettings = ClientSettings.builder()
|
||||
.requireAuthorizationConsent(true)
|
||||
.build();
|
||||
assertThat(clientSettings.isRequireAuthorizationConsent()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void settingWhenCalledThenReturnClientSettings() {
|
||||
ClientSettings clientSettings = new ClientSettings()
|
||||
.<ClientSettings>setting("name1", "value1")
|
||||
.requireProofKey(true)
|
||||
.<ClientSettings>settings(settings -> settings.put("name2", "value2"))
|
||||
.requireAuthorizationConsent(true);
|
||||
assertThat(clientSettings.settings()).hasSize(4);
|
||||
assertThat(clientSettings.requireProofKey()).isTrue();
|
||||
assertThat(clientSettings.requireAuthorizationConsent()).isTrue();
|
||||
assertThat(clientSettings.<String>setting("name1")).isEqualTo("value1");
|
||||
assertThat(clientSettings.<String>setting("name2")).isEqualTo("value2");
|
||||
public void settingWhenCustomThenSet() {
|
||||
ClientSettings clientSettings = ClientSettings.builder()
|
||||
.setting("name1", "value1")
|
||||
.settings(settings -> settings.put("name2", "value2"))
|
||||
.build();
|
||||
assertThat(clientSettings.getSettings()).hasSize(4);
|
||||
assertThat(clientSettings.<String>getSetting("name1")).isEqualTo("value1");
|
||||
assertThat(clientSettings.<String>getSetting("name2")).isEqualTo("value2");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,20 +28,20 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
public class ProviderSettingsTests {
|
||||
|
||||
@Test
|
||||
public void constructorWhenDefaultThenDefaultsAreSet() {
|
||||
ProviderSettings providerSettings = new ProviderSettings();
|
||||
public void buildWhenDefaultThenDefaultsAreSet() {
|
||||
ProviderSettings providerSettings = ProviderSettings.builder().build();
|
||||
|
||||
assertThat(providerSettings.issuer()).isNull();
|
||||
assertThat(providerSettings.authorizationEndpoint()).isEqualTo("/oauth2/authorize");
|
||||
assertThat(providerSettings.tokenEndpoint()).isEqualTo("/oauth2/token");
|
||||
assertThat(providerSettings.jwkSetEndpoint()).isEqualTo("/oauth2/jwks");
|
||||
assertThat(providerSettings.tokenRevocationEndpoint()).isEqualTo("/oauth2/revoke");
|
||||
assertThat(providerSettings.tokenIntrospectionEndpoint()).isEqualTo("/oauth2/introspect");
|
||||
assertThat(providerSettings.oidcClientRegistrationEndpoint()).isEqualTo("/connect/register");
|
||||
assertThat(providerSettings.getIssuer()).isNull();
|
||||
assertThat(providerSettings.getAuthorizationEndpoint()).isEqualTo("/oauth2/authorize");
|
||||
assertThat(providerSettings.getTokenEndpoint()).isEqualTo("/oauth2/token");
|
||||
assertThat(providerSettings.getJwkSetEndpoint()).isEqualTo("/oauth2/jwks");
|
||||
assertThat(providerSettings.getTokenRevocationEndpoint()).isEqualTo("/oauth2/revoke");
|
||||
assertThat(providerSettings.getTokenIntrospectionEndpoint()).isEqualTo("/oauth2/introspect");
|
||||
assertThat(providerSettings.getOidcClientRegistrationEndpoint()).isEqualTo("/connect/register");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void settingsWhenProvidedThenSet() {
|
||||
public void buildWhenSettingsProvidedThenSet() {
|
||||
String authorizationEndpoint = "/oauth2/v1/authorize";
|
||||
String tokenEndpoint = "/oauth2/v1/token";
|
||||
String jwkSetEndpoint = "/oauth2/v1/jwks";
|
||||
@@ -50,7 +50,7 @@ public class ProviderSettingsTests {
|
||||
String oidcClientRegistrationEndpoint = "/connect/v1/register";
|
||||
String issuer = "https://example.com:9000";
|
||||
|
||||
ProviderSettings providerSettings = new ProviderSettings()
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.issuer(issuer)
|
||||
.authorizationEndpoint(authorizationEndpoint)
|
||||
.tokenEndpoint(tokenEndpoint)
|
||||
@@ -58,81 +58,76 @@ public class ProviderSettingsTests {
|
||||
.tokenRevocationEndpoint(tokenRevocationEndpoint)
|
||||
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint)
|
||||
.tokenRevocationEndpoint(tokenRevocationEndpoint)
|
||||
.oidcClientRegistrationEndpoint(oidcClientRegistrationEndpoint);
|
||||
.oidcClientRegistrationEndpoint(oidcClientRegistrationEndpoint)
|
||||
.build();
|
||||
|
||||
assertThat(providerSettings.issuer()).isEqualTo(issuer);
|
||||
assertThat(providerSettings.authorizationEndpoint()).isEqualTo(authorizationEndpoint);
|
||||
assertThat(providerSettings.tokenEndpoint()).isEqualTo(tokenEndpoint);
|
||||
assertThat(providerSettings.jwkSetEndpoint()).isEqualTo(jwkSetEndpoint);
|
||||
assertThat(providerSettings.tokenRevocationEndpoint()).isEqualTo(tokenRevocationEndpoint);
|
||||
assertThat(providerSettings.tokenIntrospectionEndpoint()).isEqualTo(tokenIntrospectionEndpoint);
|
||||
assertThat(providerSettings.oidcClientRegistrationEndpoint()).isEqualTo(oidcClientRegistrationEndpoint);
|
||||
assertThat(providerSettings.getIssuer()).isEqualTo(issuer);
|
||||
assertThat(providerSettings.getAuthorizationEndpoint()).isEqualTo(authorizationEndpoint);
|
||||
assertThat(providerSettings.getTokenEndpoint()).isEqualTo(tokenEndpoint);
|
||||
assertThat(providerSettings.getJwkSetEndpoint()).isEqualTo(jwkSetEndpoint);
|
||||
assertThat(providerSettings.getTokenRevocationEndpoint()).isEqualTo(tokenRevocationEndpoint);
|
||||
assertThat(providerSettings.getTokenIntrospectionEndpoint()).isEqualTo(tokenIntrospectionEndpoint);
|
||||
assertThat(providerSettings.getOidcClientRegistrationEndpoint()).isEqualTo(oidcClientRegistrationEndpoint);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void settingWhenCustomThenReturnAllSettings() {
|
||||
ProviderSettings providerSettings = new ProviderSettings()
|
||||
public void settingWhenCustomThenSet() {
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.setting("name1", "value1")
|
||||
.settings(settings -> settings.put("name2", "value2"));
|
||||
.settings(settings -> settings.put("name2", "value2"))
|
||||
.build();
|
||||
|
||||
assertThat(providerSettings.settings()).hasSize(8);
|
||||
assertThat(providerSettings.<String>setting("name1")).isEqualTo("value1");
|
||||
assertThat(providerSettings.<String>setting("name2")).isEqualTo("value2");
|
||||
assertThat(providerSettings.getSettings()).hasSize(8);
|
||||
assertThat(providerSettings.<String>getSetting("name1")).isEqualTo("value1");
|
||||
assertThat(providerSettings.<String>getSetting("name2")).isEqualTo("value2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void issuerWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.issuer(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().issuer(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authorizationEndpointWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.authorizationEndpoint(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().authorizationEndpoint(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tokenEndpointWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.tokenEndpoint(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().tokenEndpoint(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tokenRevocationEndpointWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.tokenRevocationEndpoint(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().tokenRevocationEndpoint(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tokenIntrospectionEndpointWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.tokenIntrospectionEndpoint(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().tokenIntrospectionEndpoint(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oidcClientRegistrationEndpointWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.oidcClientRegistrationEndpoint(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().oidcClientRegistrationEndpoint(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jwksEndpointWhenNullThenThrowIllegalArgumentException() {
|
||||
ProviderSettings settings = new ProviderSettings();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settings.jwkSetEndpoint(null))
|
||||
.isThrownBy(() -> ProviderSettings.builder().jwkSetEndpoint(null))
|
||||
.withMessage("value cannot be null");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.config;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link Settings}.
|
||||
*
|
||||
* @author Joe Grandja
|
||||
*/
|
||||
public class SettingsTests {
|
||||
|
||||
@Test
|
||||
public void constructorWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new Settings(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("settings cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenSettingsProvidedThenSettingsAreSet() {
|
||||
Map<String, Object> initialSettings = new HashMap<>();
|
||||
initialSettings.put("setting1", "value1");
|
||||
initialSettings.put("setting2", "value2");
|
||||
|
||||
Settings settings = new Settings(initialSettings)
|
||||
.setting("setting3", "value3")
|
||||
.settings(s -> s.put("setting4", "value4"));
|
||||
|
||||
assertThat(settings.settings()).contains(
|
||||
entry("setting1", "value1"),
|
||||
entry("setting2", "value2"),
|
||||
entry("setting3", "value3"),
|
||||
entry("setting4", "value4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSettingWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new Settings().setting(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSettingWhenNameNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new Settings().setting(null, "value"))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSettingWhenValueNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new Settings().setting("setting", null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("value cannot be null");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
* Copyright 2020-2021 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.
|
||||
@@ -32,42 +32,37 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
public class TokenSettingsTests {
|
||||
|
||||
@Test
|
||||
public void constructorWhenDefaultThenDefaultsAreSet() {
|
||||
TokenSettings tokenSettings = new TokenSettings();
|
||||
assertThat(tokenSettings.settings()).hasSize(4);
|
||||
assertThat(tokenSettings.accessTokenTimeToLive()).isEqualTo(Duration.ofMinutes(5));
|
||||
assertThat(tokenSettings.reuseRefreshTokens()).isTrue();
|
||||
assertThat(tokenSettings.refreshTokenTimeToLive()).isEqualTo(Duration.ofMinutes(60));
|
||||
assertThat(tokenSettings.idTokenSignatureAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenNullThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new TokenSettings(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("settings cannot be null");
|
||||
public void buildWhenDefaultThenDefaultsAreSet() {
|
||||
TokenSettings tokenSettings = TokenSettings.builder().build();
|
||||
assertThat(tokenSettings.getSettings()).hasSize(4);
|
||||
assertThat(tokenSettings.getAccessTokenTimeToLive()).isEqualTo(Duration.ofMinutes(5));
|
||||
assertThat(tokenSettings.isReuseRefreshTokens()).isTrue();
|
||||
assertThat(tokenSettings.getRefreshTokenTimeToLive()).isEqualTo(Duration.ofMinutes(60));
|
||||
assertThat(tokenSettings.getIdTokenSignatureAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessTokenTimeToLiveWhenProvidedThenSet() {
|
||||
Duration accessTokenTimeToLive = Duration.ofMinutes(10);
|
||||
TokenSettings tokenSettings = new TokenSettings().accessTokenTimeToLive(accessTokenTimeToLive);
|
||||
assertThat(tokenSettings.accessTokenTimeToLive()).isEqualTo(accessTokenTimeToLive);
|
||||
TokenSettings tokenSettings = TokenSettings.builder()
|
||||
.accessTokenTimeToLive(accessTokenTimeToLive)
|
||||
.build();
|
||||
assertThat(tokenSettings.getAccessTokenTimeToLive()).isEqualTo(accessTokenTimeToLive);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessTokenTimeToLiveWhenNullOrZeroOrNegativeThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new TokenSettings().accessTokenTimeToLive(null))
|
||||
assertThatThrownBy(() -> TokenSettings.builder().accessTokenTimeToLive(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("accessTokenTimeToLive cannot be null");
|
||||
|
||||
assertThatThrownBy(() -> new TokenSettings().accessTokenTimeToLive(Duration.ZERO))
|
||||
assertThatThrownBy(() -> TokenSettings.builder().accessTokenTimeToLive(Duration.ZERO))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("accessTokenTimeToLive must be greater than Duration.ZERO");
|
||||
|
||||
assertThatThrownBy(() -> new TokenSettings().accessTokenTimeToLive(Duration.ofSeconds(-10)))
|
||||
assertThatThrownBy(() -> TokenSettings.builder().accessTokenTimeToLive(Duration.ofSeconds(-10)))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("accessTokenTimeToLive must be greater than Duration.ZERO");
|
||||
@@ -75,30 +70,34 @@ public class TokenSettingsTests {
|
||||
|
||||
@Test
|
||||
public void reuseRefreshTokensWhenFalseThenSet() {
|
||||
TokenSettings tokenSettings = new TokenSettings().reuseRefreshTokens(false);
|
||||
assertThat(tokenSettings.reuseRefreshTokens()).isFalse();
|
||||
TokenSettings tokenSettings = TokenSettings.builder()
|
||||
.reuseRefreshTokens(false)
|
||||
.build();
|
||||
assertThat(tokenSettings.isReuseRefreshTokens()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshTokenTimeToLiveWhenProvidedThenSet() {
|
||||
Duration refreshTokenTimeToLive = Duration.ofDays(10);
|
||||
TokenSettings tokenSettings = new TokenSettings().refreshTokenTimeToLive(refreshTokenTimeToLive);
|
||||
assertThat(tokenSettings.refreshTokenTimeToLive()).isEqualTo(refreshTokenTimeToLive);
|
||||
TokenSettings tokenSettings = TokenSettings.builder()
|
||||
.refreshTokenTimeToLive(refreshTokenTimeToLive)
|
||||
.build();
|
||||
assertThat(tokenSettings.getRefreshTokenTimeToLive()).isEqualTo(refreshTokenTimeToLive);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshTokenTimeToLiveWhenNullOrZeroOrNegativeThenThrowIllegalArgumentException() {
|
||||
assertThatThrownBy(() -> new TokenSettings().refreshTokenTimeToLive(null))
|
||||
assertThatThrownBy(() -> TokenSettings.builder().refreshTokenTimeToLive(null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("refreshTokenTimeToLive cannot be null");
|
||||
|
||||
assertThatThrownBy(() -> new TokenSettings().refreshTokenTimeToLive(Duration.ZERO))
|
||||
assertThatThrownBy(() -> TokenSettings.builder().refreshTokenTimeToLive(Duration.ZERO))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("refreshTokenTimeToLive must be greater than Duration.ZERO");
|
||||
|
||||
assertThatThrownBy(() -> new TokenSettings().refreshTokenTimeToLive(Duration.ofSeconds(-10)))
|
||||
assertThatThrownBy(() -> TokenSettings.builder().refreshTokenTimeToLive(Duration.ofSeconds(-10)))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.extracting(Throwable::getMessage)
|
||||
.isEqualTo("refreshTokenTimeToLive must be greater than Duration.ZERO");
|
||||
@@ -107,23 +106,21 @@ public class TokenSettingsTests {
|
||||
@Test
|
||||
public void idTokenSignatureAlgorithmWhenProvidedThenSet() {
|
||||
SignatureAlgorithm idTokenSignatureAlgorithm = SignatureAlgorithm.RS512;
|
||||
TokenSettings tokenSettings = new TokenSettings().idTokenSignatureAlgorithm(idTokenSignatureAlgorithm);
|
||||
assertThat(tokenSettings.idTokenSignatureAlgorithm()).isEqualTo(idTokenSignatureAlgorithm);
|
||||
TokenSettings tokenSettings = TokenSettings.builder()
|
||||
.idTokenSignatureAlgorithm(idTokenSignatureAlgorithm)
|
||||
.build();
|
||||
assertThat(tokenSettings.getIdTokenSignatureAlgorithm()).isEqualTo(idTokenSignatureAlgorithm);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void settingWhenCalledThenReturnTokenSettings() {
|
||||
Duration accessTokenTimeToLive = Duration.ofMinutes(10);
|
||||
TokenSettings tokenSettings = new TokenSettings()
|
||||
.<TokenSettings>setting("name1", "value1")
|
||||
.accessTokenTimeToLive(accessTokenTimeToLive)
|
||||
.settings(settings -> settings.put("name2", "value2"));
|
||||
assertThat(tokenSettings.settings()).hasSize(6);
|
||||
assertThat(tokenSettings.accessTokenTimeToLive()).isEqualTo(accessTokenTimeToLive);
|
||||
assertThat(tokenSettings.reuseRefreshTokens()).isTrue();
|
||||
assertThat(tokenSettings.refreshTokenTimeToLive()).isEqualTo(Duration.ofMinutes(60));
|
||||
assertThat(tokenSettings.idTokenSignatureAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
assertThat(tokenSettings.<String>setting("name1")).isEqualTo("value1");
|
||||
assertThat(tokenSettings.<String>setting("name2")).isEqualTo("value2");
|
||||
public void settingWhenCustomThenSet() {
|
||||
TokenSettings tokenSettings = TokenSettings.builder()
|
||||
.setting("name1", "value1")
|
||||
.settings(settings -> settings.put("name2", "value2"))
|
||||
.build();
|
||||
assertThat(tokenSettings.getSettings()).hasSize(6);
|
||||
assertThat(tokenSettings.<String>getSetting("name1")).isEqualTo("value1");
|
||||
assertThat(tokenSettings.<String>getSetting("name2")).isEqualTo("value2");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -264,9 +264,9 @@ public class OidcClientRegistrationAuthenticationProviderTests {
|
||||
assertThat(registeredClientResult.getAuthorizationGrantTypes())
|
||||
.containsExactlyInAnyOrder(AuthorizationGrantType.AUTHORIZATION_CODE, AuthorizationGrantType.CLIENT_CREDENTIALS);
|
||||
assertThat(registeredClientResult.getScopes()).containsExactlyInAnyOrder("scope1", "scope2");
|
||||
assertThat(registeredClientResult.getClientSettings().requireProofKey()).isTrue();
|
||||
assertThat(registeredClientResult.getClientSettings().requireAuthorizationConsent()).isTrue();
|
||||
assertThat(registeredClientResult.getTokenSettings().idTokenSignatureAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
assertThat(registeredClientResult.getClientSettings().isRequireProofKey()).isTrue();
|
||||
assertThat(registeredClientResult.getClientSettings().isRequireAuthorizationConsent()).isTrue();
|
||||
assertThat(registeredClientResult.getTokenSettings().getIdTokenSignatureAlgorithm()).isEqualTo(SignatureAlgorithm.RS256);
|
||||
|
||||
OidcClientRegistration clientRegistrationResult = authenticationResult.getClientRegistration();
|
||||
assertThat(clientRegistrationResult.getClientId()).isEqualTo(registeredClientResult.getClientId());
|
||||
@@ -289,7 +289,7 @@ public class OidcClientRegistrationAuthenticationProviderTests {
|
||||
assertThat(clientRegistrationResult.getTokenEndpointAuthenticationMethod())
|
||||
.isEqualTo(registeredClientResult.getClientAuthenticationMethods().iterator().next().getValue());
|
||||
assertThat(clientRegistrationResult.getIdTokenSignedResponseAlgorithm())
|
||||
.isEqualTo(registeredClientResult.getTokenSettings().idTokenSignatureAlgorithm().getName());
|
||||
.isEqualTo(registeredClientResult.getTokenSettings().getIdTokenSignatureAlgorithm().getName());
|
||||
}
|
||||
|
||||
private static Jwt createJwt() {
|
||||
|
||||
@@ -15,16 +15,17 @@
|
||||
*/
|
||||
package org.springframework.security.oauth2.server.authorization.oidc.web;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -50,7 +51,7 @@ public class OidcProviderConfigurationEndpointFilterTests {
|
||||
@Test
|
||||
public void doFilterWhenNotConfigurationRequestThenNotProcessed() throws Exception {
|
||||
OidcProviderConfigurationEndpointFilter filter =
|
||||
new OidcProviderConfigurationEndpointFilter(new ProviderSettings());
|
||||
new OidcProviderConfigurationEndpointFilter(ProviderSettings.builder().build());
|
||||
|
||||
String requestUri = "/path";
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
@@ -66,7 +67,7 @@ public class OidcProviderConfigurationEndpointFilterTests {
|
||||
@Test
|
||||
public void doFilterWhenConfigurationRequestPostThenNotProcessed() throws Exception {
|
||||
OidcProviderConfigurationEndpointFilter filter =
|
||||
new OidcProviderConfigurationEndpointFilter(new ProviderSettings());
|
||||
new OidcProviderConfigurationEndpointFilter(ProviderSettings.builder().build());
|
||||
|
||||
String requestUri = DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI;
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", requestUri);
|
||||
@@ -85,11 +86,12 @@ public class OidcProviderConfigurationEndpointFilterTests {
|
||||
String tokenEndpoint = "/oauth2/v1/token";
|
||||
String jwkSetEndpoint = "/oauth2/v1/jwks";
|
||||
|
||||
ProviderSettings providerSettings = new ProviderSettings()
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.issuer("https://example.com/issuer1")
|
||||
.authorizationEndpoint(authorizationEndpoint)
|
||||
.tokenEndpoint(tokenEndpoint)
|
||||
.jwkSetEndpoint(jwkSetEndpoint);
|
||||
.jwkSetEndpoint(jwkSetEndpoint)
|
||||
.build();
|
||||
OidcProviderConfigurationEndpointFilter filter =
|
||||
new OidcProviderConfigurationEndpointFilter(providerSettings);
|
||||
|
||||
@@ -119,8 +121,9 @@ public class OidcProviderConfigurationEndpointFilterTests {
|
||||
|
||||
@Test
|
||||
public void doFilterWhenProviderSettingsWithInvalidIssuerThenThrowIllegalArgumentException() {
|
||||
ProviderSettings providerSettings = new ProviderSettings()
|
||||
.issuer("https://this is an invalid URL");
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.issuer("https://this is an invalid URL")
|
||||
.build();
|
||||
OidcProviderConfigurationEndpointFilter filter =
|
||||
new OidcProviderConfigurationEndpointFilter(providerSettings);
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ public class OAuth2AuthorizationServerMetadataEndpointFilterTests {
|
||||
@Test
|
||||
public void doFilterWhenNotAuthorizationServerMetadataRequestThenNotProcessed() throws Exception {
|
||||
OAuth2AuthorizationServerMetadataEndpointFilter filter =
|
||||
new OAuth2AuthorizationServerMetadataEndpointFilter(new ProviderSettings().issuer("https://example.com"));
|
||||
new OAuth2AuthorizationServerMetadataEndpointFilter(ProviderSettings.builder().issuer("https://example.com").build());
|
||||
|
||||
String requestUri = "/path";
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
||||
@@ -68,7 +68,7 @@ public class OAuth2AuthorizationServerMetadataEndpointFilterTests {
|
||||
@Test
|
||||
public void doFilterWhenAuthorizationServerMetadataRequestPostThenNotProcessed() throws Exception {
|
||||
OAuth2AuthorizationServerMetadataEndpointFilter filter =
|
||||
new OAuth2AuthorizationServerMetadataEndpointFilter(new ProviderSettings().issuer("https://example.com"));
|
||||
new OAuth2AuthorizationServerMetadataEndpointFilter(ProviderSettings.builder().issuer("https://example.com").build());
|
||||
|
||||
String requestUri = DEFAULT_OAUTH2_AUTHORIZATION_SERVER_METADATA_ENDPOINT_URI;
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", requestUri);
|
||||
@@ -89,13 +89,14 @@ public class OAuth2AuthorizationServerMetadataEndpointFilterTests {
|
||||
String tokenRevocationEndpoint = "/oauth2/v1/revoke";
|
||||
String tokenIntrospectionEndpoint = "/oauth2/v1/introspect";
|
||||
|
||||
ProviderSettings providerSettings = new ProviderSettings()
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.issuer("https://example.com/issuer1")
|
||||
.authorizationEndpoint(authorizationEndpoint)
|
||||
.tokenEndpoint(tokenEndpoint)
|
||||
.jwkSetEndpoint(jwkSetEndpoint)
|
||||
.tokenRevocationEndpoint(tokenRevocationEndpoint)
|
||||
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint);
|
||||
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint)
|
||||
.build();
|
||||
OAuth2AuthorizationServerMetadataEndpointFilter filter =
|
||||
new OAuth2AuthorizationServerMetadataEndpointFilter(providerSettings);
|
||||
|
||||
@@ -127,8 +128,9 @@ public class OAuth2AuthorizationServerMetadataEndpointFilterTests {
|
||||
|
||||
@Test
|
||||
public void doFilterWhenProviderSettingsWithInvalidIssuerThenThrowIllegalArgumentException() {
|
||||
ProviderSettings providerSettings = new ProviderSettings()
|
||||
.issuer("https://this is an invalid URL");
|
||||
ProviderSettings providerSettings = ProviderSettings.builder()
|
||||
.issuer("https://this is an invalid URL")
|
||||
.build();
|
||||
OAuth2AuthorizationServerMetadataEndpointFilter filter =
|
||||
new OAuth2AuthorizationServerMetadataEndpointFilter(providerSettings);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
|
||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
@@ -86,7 +87,7 @@ public class AuthorizationServerConfig {
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope("message.read")
|
||||
.scope("message.write")
|
||||
.clientSettings(clientSettings -> clientSettings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
return new InMemoryRegisteredClientRepository(registeredClient);
|
||||
}
|
||||
@@ -101,7 +102,7 @@ public class AuthorizationServerConfig {
|
||||
|
||||
@Bean
|
||||
public ProviderSettings providerSettings() {
|
||||
return new ProviderSettings().issuer("http://auth-server:9000");
|
||||
return ProviderSettings.builder().issuer("http://auth-server:9000").build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
|
||||
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ClientSettings;
|
||||
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
|
||||
@@ -77,7 +78,7 @@ public class AuthorizationServerConfig {
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope("message.read")
|
||||
.scope("message.write")
|
||||
.clientSettings(clientSettings -> clientSettings.requireAuthorizationConsent(true))
|
||||
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
|
||||
.build();
|
||||
|
||||
// Save registered client in db as if in-memory
|
||||
@@ -112,7 +113,7 @@ public class AuthorizationServerConfig {
|
||||
|
||||
@Bean
|
||||
public ProviderSettings providerSettings() {
|
||||
return new ProviderSettings().issuer("http://auth-server:9000");
|
||||
return ProviderSettings.builder().issuer("http://auth-server:9000").build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user