Browse Source

Extract configurer for OpenID Connect 1.0 support

Issue gh-398
pull/411/head
Joe Grandja 5 years ago
parent
commit
fe27e39c5d
  1. 74
      oauth2-authorization-server/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java
  2. 102
      oauth2-authorization-server/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java

74
oauth2-authorization-server/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java

@ -19,9 +19,6 @@ import java.net.URI; @@ -19,9 +19,6 @@ import java.net.URI;
import java.util.LinkedHashMap;
import java.util.Map;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
@ -35,9 +32,6 @@ import org.springframework.security.oauth2.server.authorization.authentication.O @@ -35,9 +32,6 @@ import org.springframework.security.oauth2.server.authorization.authentication.O
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2TokenRevocationAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcClientRegistrationEndpointFilter;
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcProviderConfigurationEndpointFilter;
import org.springframework.security.oauth2.server.authorization.web.NimbusJwkSetEndpointFilter;
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationServerMetadataEndpointFilter;
import org.springframework.security.oauth2.server.authorization.web.OAuth2TokenIntrospectionEndpointFilter;
@ -62,15 +56,14 @@ import org.springframework.util.Assert; @@ -62,15 +56,14 @@ import org.springframework.util.Assert;
* @see OAuth2ClientAuthenticationConfigurer
* @see OAuth2AuthorizationEndpointConfigurer
* @see OAuth2TokenEndpointConfigurer
* @see OidcConfigurer
* @see RegisteredClientRepository
* @see OAuth2AuthorizationService
* @see OAuth2AuthorizationConsentService
* @see OAuth2TokenIntrospectionEndpointFilter
* @see OAuth2TokenRevocationEndpointFilter
* @see NimbusJwkSetEndpointFilter
* @see OidcProviderConfigurationEndpointFilter
* @see OAuth2AuthorizationServerMetadataEndpointFilter
* @see OidcClientRegistrationEndpointFilter
*/
public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBuilder<B>>
extends AbstractHttpConfigurer<OAuth2AuthorizationServerConfigurer<B>, B> {
@ -79,18 +72,15 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -79,18 +72,15 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
private RequestMatcher tokenIntrospectionEndpointMatcher;
private RequestMatcher tokenRevocationEndpointMatcher;
private RequestMatcher jwkSetEndpointMatcher;
private RequestMatcher oidcProviderConfigurationEndpointMatcher;
private RequestMatcher authorizationServerMetadataEndpointMatcher;
private RequestMatcher oidcClientRegistrationEndpointMatcher;
private final RequestMatcher endpointsMatcher = (request) ->
getRequestMatcher(OAuth2AuthorizationEndpointConfigurer.class).matches(request) ||
getRequestMatcher(OAuth2TokenEndpointConfigurer.class).matches(request) ||
getRequestMatcher(OidcConfigurer.class).matches(request) ||
this.tokenIntrospectionEndpointMatcher.matches(request) ||
this.tokenRevocationEndpointMatcher.matches(request) ||
this.jwkSetEndpointMatcher.matches(request) ||
this.oidcProviderConfigurationEndpointMatcher.matches(request) ||
this.authorizationServerMetadataEndpointMatcher.matches(request) ||
this.oidcClientRegistrationEndpointMatcher.matches(request);
this.authorizationServerMetadataEndpointMatcher.matches(request);
/**
* Sets the repository of registered clients.
@ -173,6 +163,17 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -173,6 +163,17 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
return this;
}
/**
* Configures OpenID Connect 1.0 support.
*
* @param oidcCustomizer the {@link Customizer} providing access to the {@link OidcConfigurer}
* @return the {@link OAuth2AuthorizationServerConfigurer} for further configuration
*/
public OAuth2AuthorizationServerConfigurer<B> oidc(Customizer<OidcConfigurer> oidcCustomizer) {
oidcCustomizer.customize(getConfigurer(OidcConfigurer.class));
return this;
}
/**
* Returns a {@link RequestMatcher} for the authorization server endpoints.
*
@ -201,13 +202,6 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -201,13 +202,6 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
OAuth2ConfigurerUtils.getAuthorizationService(builder));
builder.authenticationProvider(postProcess(tokenRevocationAuthenticationProvider));
// TODO Make OpenID Client Registration an "opt-in" feature
OidcClientRegistrationAuthenticationProvider oidcClientRegistrationAuthenticationProvider =
new OidcClientRegistrationAuthenticationProvider(
OAuth2ConfigurerUtils.getRegisteredClientRepository(builder),
OAuth2ConfigurerUtils.getAuthorizationService(builder));
builder.authenticationProvider(postProcess(oidcClientRegistrationAuthenticationProvider));
ExceptionHandlingConfigurer<B> exceptionHandling = builder.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling != null) {
exceptionHandling.defaultAuthenticationEntryPointFor(
@ -225,22 +219,6 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -225,22 +219,6 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
this.configurers.values().forEach(configurer -> configurer.configure(builder));
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
if (providerSettings.getIssuer() != null) {
OidcProviderConfigurationEndpointFilter oidcProviderConfigurationEndpointFilter =
new OidcProviderConfigurationEndpointFilter(providerSettings);
builder.addFilterBefore(postProcess(oidcProviderConfigurationEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
OAuth2AuthorizationServerMetadataEndpointFilter authorizationServerMetadataEndpointFilter =
new OAuth2AuthorizationServerMetadataEndpointFilter(providerSettings);
builder.addFilterBefore(postProcess(authorizationServerMetadataEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
}
JWKSource<SecurityContext> jwkSource = OAuth2ConfigurerUtils.getJwkSource(builder);
NimbusJwkSetEndpointFilter jwkSetEndpointFilter = new NimbusJwkSetEndpointFilter(
jwkSource,
providerSettings.getJwkSetEndpoint());
builder.addFilterBefore(postProcess(jwkSetEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class);
OAuth2TokenIntrospectionEndpointFilter tokenIntrospectionEndpointFilter =
@ -253,14 +231,19 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -253,14 +231,19 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
new OAuth2TokenRevocationEndpointFilter(
authenticationManager,
providerSettings.getTokenRevocationEndpoint());
builder.addFilterAfter(postProcess(tokenRevocationEndpointFilter), OAuth2TokenIntrospectionEndpointFilter.class);
builder.addFilterAfter(postProcess(tokenRevocationEndpointFilter), FilterSecurityInterceptor.class);
// TODO Make OpenID Client Registration an "opt-in" feature
OidcClientRegistrationEndpointFilter oidcClientRegistrationEndpointFilter =
new OidcClientRegistrationEndpointFilter(
authenticationManager,
providerSettings.getOidcClientRegistrationEndpoint());
builder.addFilterAfter(postProcess(oidcClientRegistrationEndpointFilter), OAuth2TokenRevocationEndpointFilter.class);
NimbusJwkSetEndpointFilter jwkSetEndpointFilter =
new NimbusJwkSetEndpointFilter(
OAuth2ConfigurerUtils.getJwkSource(builder),
providerSettings.getJwkSetEndpoint());
builder.addFilterBefore(postProcess(jwkSetEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
if (providerSettings.getIssuer() != null) {
OAuth2AuthorizationServerMetadataEndpointFilter authorizationServerMetadataEndpointFilter =
new OAuth2AuthorizationServerMetadataEndpointFilter(providerSettings);
builder.addFilterBefore(postProcess(authorizationServerMetadataEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
}
}
private Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> createConfigurers() {
@ -268,6 +251,7 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -268,6 +251,7 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
configurers.put(OAuth2ClientAuthenticationConfigurer.class, new OAuth2ClientAuthenticationConfigurer(this::postProcess));
configurers.put(OAuth2AuthorizationEndpointConfigurer.class, new OAuth2AuthorizationEndpointConfigurer(this::postProcess));
configurers.put(OAuth2TokenEndpointConfigurer.class, new OAuth2TokenEndpointConfigurer(this::postProcess));
configurers.put(OidcConfigurer.class, new OidcConfigurer(this::postProcess));
return configurers;
}
@ -287,12 +271,8 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -287,12 +271,8 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
providerSettings.getTokenRevocationEndpoint(), HttpMethod.POST.name());
this.jwkSetEndpointMatcher = new AntPathRequestMatcher(
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.getOidcClientRegistrationEndpoint(), HttpMethod.POST.name());
}
private static void validateProviderSettings(ProviderSettings providerSettings) {

102
oauth2-authorization-server/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
/*
* 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.config.annotation.web.configurers.oauth2.server.authorization;
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcClientRegistrationEndpointFilter;
import org.springframework.security.oauth2.server.authorization.oidc.web.OidcProviderConfigurationEndpointFilter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
/**
* Configurer for OpenID Connect 1.0 support.
*
* @author Joe Grandja
* @since 0.2.0
* @see OAuth2AuthorizationServerConfigurer#oidc
* @see OidcProviderConfigurationEndpointFilter
* @see OidcClientRegistrationEndpointFilter
*/
public final class OidcConfigurer extends AbstractOAuth2Configurer {
private RequestMatcher requestMatcher;
/**
* Restrict for internal use only.
*/
OidcConfigurer(ObjectPostProcessor<Object> objectPostProcessor) {
super(objectPostProcessor);
}
@Override
<B extends HttpSecurityBuilder<B>> void init(B builder) {
List<RequestMatcher> requestMatchers = new ArrayList<>();
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
if (providerSettings.getIssuer() != null) {
requestMatchers.add(
new AntPathRequestMatcher(
"/.well-known/openid-configuration",
HttpMethod.GET.name()));
}
requestMatchers.add(
new AntPathRequestMatcher(
providerSettings.getOidcClientRegistrationEndpoint(),
HttpMethod.POST.name()));
this.requestMatcher = new OrRequestMatcher(requestMatchers);
// TODO Make OpenID Client Registration an "opt-in" feature
OidcClientRegistrationAuthenticationProvider oidcClientRegistrationAuthenticationProvider =
new OidcClientRegistrationAuthenticationProvider(
OAuth2ConfigurerUtils.getRegisteredClientRepository(builder),
OAuth2ConfigurerUtils.getAuthorizationService(builder));
builder.authenticationProvider(postProcess(oidcClientRegistrationAuthenticationProvider));
}
@Override
<B extends HttpSecurityBuilder<B>> void configure(B builder) {
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
if (providerSettings.getIssuer() != null) {
OidcProviderConfigurationEndpointFilter oidcProviderConfigurationEndpointFilter =
new OidcProviderConfigurationEndpointFilter(providerSettings);
builder.addFilterBefore(postProcess(oidcProviderConfigurationEndpointFilter), AbstractPreAuthenticatedProcessingFilter.class);
}
AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class);
// TODO Make OpenID Client Registration an "opt-in" feature
OidcClientRegistrationEndpointFilter oidcClientRegistrationEndpointFilter =
new OidcClientRegistrationEndpointFilter(
authenticationManager,
providerSettings.getOidcClientRegistrationEndpoint());
builder.addFilterAfter(postProcess(oidcClientRegistrationEndpointFilter), FilterSecurityInterceptor.class);
}
@Override
RequestMatcher getRequestMatcher() {
return this.requestMatcher;
}
}
Loading…
Cancel
Save