Browse Source

Fix expected @Transient Authentication at provider configuration endpoint

Closes gh-632
pull/679/head
Joe Grandja 4 years ago
parent
commit
ccf4a2de6e
  1. 42
      oauth2-authorization-server/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OAuth2AuthorizationServerConfigurer.java
  2. 54
      oauth2-authorization-server/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcConfigurer.java
  3. 10
      oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java

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

@ -16,7 +16,9 @@ @@ -16,7 +16,9 @@
package org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.AsyncContext;
@ -270,16 +272,9 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -270,16 +272,9 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
}
SecurityContextRepository securityContextRepositoryTransientNotSaved = new SecurityContextRepository() {
// OAuth2ClientAuthenticationToken is @Transient and is accepted by
// OAuth2TokenEndpointFilter, OAuth2TokenIntrospectionEndpointFilter and OAuth2TokenRevocationEndpointFilter
private final RequestMatcher clientAuthenticationRequestMatcher = new OrRequestMatcher(
getRequestMatcher(OAuth2TokenEndpointConfigurer.class),
getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class),
OAuth2AuthorizationServerConfigurer.this.tokenIntrospectionEndpointMatcher);
// JwtAuthenticationToken is @Transient and is accepted by
// OidcUserInfoEndpointFilter and OidcClientRegistrationEndpointFilter
private final RequestMatcher jwtAuthenticationRequestMatcher = getRequestMatcher(OidcConfigurer.class);
private final RequestMatcher clientAuthenticationRequestMatcher = initClientAuthenticationRequestMatcher();
private final RequestMatcher jwtAuthenticationRequestMatcher = initJwtAuthenticationRequestMatcher();
@Override
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
@ -348,6 +343,35 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui @@ -348,6 +343,35 @@ public final class OAuth2AuthorizationServerConfigurer<B extends HttpSecurityBui
return AnnotationUtils.getAnnotation(authentication.getClass(), Transient.class) != null;
}
private RequestMatcher initClientAuthenticationRequestMatcher() {
// OAuth2ClientAuthenticationToken is @Transient and is accepted by
// OAuth2TokenEndpointFilter, OAuth2TokenIntrospectionEndpointFilter and OAuth2TokenRevocationEndpointFilter
List<RequestMatcher> requestMatchers = new ArrayList<>();
requestMatchers.add(getRequestMatcher(OAuth2TokenEndpointConfigurer.class));
requestMatchers.add(getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class));
requestMatchers.add(OAuth2AuthorizationServerConfigurer.this.tokenIntrospectionEndpointMatcher);
return new OrRequestMatcher(requestMatchers);
}
private RequestMatcher initJwtAuthenticationRequestMatcher() {
// JwtAuthenticationToken is @Transient and is accepted by
// OidcUserInfoEndpointFilter and OidcClientRegistrationEndpointFilter
List<RequestMatcher> requestMatchers = new ArrayList<>();
requestMatchers.add(
getConfigurer(OidcConfigurer.class)
.getConfigurer(OidcUserInfoEndpointConfigurer.class).getRequestMatcher()
);
OidcClientRegistrationEndpointConfigurer clientRegistrationEndpointConfigurer =
getConfigurer(OidcConfigurer.class)
.getConfigurer(OidcClientRegistrationEndpointConfigurer.class);
if (clientRegistrationEndpointConfigurer != null) {
requestMatchers.add(clientRegistrationEndpointConfigurer.getRequestMatcher());
}
return new OrRequestMatcher(requestMatchers);
}
};
builder.setSharedObject(SecurityContextRepository.class, securityContextRepositoryTransientNotSaved);

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

@ -16,7 +16,9 @@ @@ -16,7 +16,9 @@
package org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
@ -40,8 +42,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher; @@ -40,8 +42,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
* @see OidcProviderConfigurationEndpointFilter
*/
public final class OidcConfigurer extends AbstractOAuth2Configurer {
private final OidcUserInfoEndpointConfigurer userInfoEndpointConfigurer;
private OidcClientRegistrationEndpointConfigurer clientRegistrationEndpointConfigurer;
private final Map<Class<? extends AbstractOAuth2Configurer>, AbstractOAuth2Configurer> configurers = new LinkedHashMap<>();
private RequestMatcher requestMatcher;
/**
@ -49,7 +50,7 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer { @@ -49,7 +50,7 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer {
*/
OidcConfigurer(ObjectPostProcessor<Object> objectPostProcessor) {
super(objectPostProcessor);
this.userInfoEndpointConfigurer = new OidcUserInfoEndpointConfigurer(objectPostProcessor);
addConfigurer(OidcUserInfoEndpointConfigurer.class, new OidcUserInfoEndpointConfigurer(objectPostProcessor));
}
/**
@ -59,10 +60,14 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer { @@ -59,10 +60,14 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer {
* @return the {@link OidcConfigurer} for further configuration
*/
public OidcConfigurer clientRegistrationEndpoint(Customizer<OidcClientRegistrationEndpointConfigurer> clientRegistrationEndpointCustomizer) {
if (this.clientRegistrationEndpointConfigurer == null) {
this.clientRegistrationEndpointConfigurer = new OidcClientRegistrationEndpointConfigurer(getObjectPostProcessor());
OidcClientRegistrationEndpointConfigurer clientRegistrationEndpointConfigurer =
getConfigurer(OidcClientRegistrationEndpointConfigurer.class);
if (clientRegistrationEndpointConfigurer == null) {
addConfigurer(OidcClientRegistrationEndpointConfigurer.class,
new OidcClientRegistrationEndpointConfigurer(getObjectPostProcessor()));
clientRegistrationEndpointConfigurer = getConfigurer(OidcClientRegistrationEndpointConfigurer.class);
}
clientRegistrationEndpointCustomizer.customize(this.clientRegistrationEndpointConfigurer);
clientRegistrationEndpointCustomizer.customize(clientRegistrationEndpointConfigurer);
return this;
}
@ -73,32 +78,40 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer { @@ -73,32 +78,40 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer {
* @return the {@link OidcConfigurer} for further configuration
*/
public OidcConfigurer userInfoEndpoint(Customizer<OidcUserInfoEndpointConfigurer> userInfoEndpointCustomizer) {
userInfoEndpointCustomizer.customize(this.userInfoEndpointConfigurer);
userInfoEndpointCustomizer.customize(getConfigurer(OidcUserInfoEndpointConfigurer.class));
return this;
}
@Override
<B extends HttpSecurityBuilder<B>> void init(B builder) {
this.userInfoEndpointConfigurer.init(builder);
if (this.clientRegistrationEndpointConfigurer != null) {
this.clientRegistrationEndpointConfigurer.init(builder);
OidcUserInfoEndpointConfigurer userInfoEndpointConfigurer =
getConfigurer(OidcUserInfoEndpointConfigurer.class);
userInfoEndpointConfigurer.init(builder);
OidcClientRegistrationEndpointConfigurer clientRegistrationEndpointConfigurer =
getConfigurer(OidcClientRegistrationEndpointConfigurer.class);
if (clientRegistrationEndpointConfigurer != null) {
clientRegistrationEndpointConfigurer.init(builder);
}
List<RequestMatcher> requestMatchers = new ArrayList<>();
requestMatchers.add(new AntPathRequestMatcher(
"/.well-known/openid-configuration", HttpMethod.GET.name()));
requestMatchers.add(this.userInfoEndpointConfigurer.getRequestMatcher());
if (this.clientRegistrationEndpointConfigurer != null) {
requestMatchers.add(this.clientRegistrationEndpointConfigurer.getRequestMatcher());
requestMatchers.add(userInfoEndpointConfigurer.getRequestMatcher());
if (clientRegistrationEndpointConfigurer != null) {
requestMatchers.add(clientRegistrationEndpointConfigurer.getRequestMatcher());
}
this.requestMatcher = new OrRequestMatcher(requestMatchers);
}
@Override
<B extends HttpSecurityBuilder<B>> void configure(B builder) {
this.userInfoEndpointConfigurer.configure(builder);
if (this.clientRegistrationEndpointConfigurer != null) {
this.clientRegistrationEndpointConfigurer.configure(builder);
OidcUserInfoEndpointConfigurer userInfoEndpointConfigurer =
getConfigurer(OidcUserInfoEndpointConfigurer.class);
userInfoEndpointConfigurer.configure(builder);
OidcClientRegistrationEndpointConfigurer clientRegistrationEndpointConfigurer =
getConfigurer(OidcClientRegistrationEndpointConfigurer.class);
if (clientRegistrationEndpointConfigurer != null) {
clientRegistrationEndpointConfigurer.configure(builder);
}
ProviderSettings providerSettings = OAuth2ConfigurerUtils.getProviderSettings(builder);
@ -112,4 +125,13 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer { @@ -112,4 +125,13 @@ public final class OidcConfigurer extends AbstractOAuth2Configurer {
return this.requestMatcher;
}
@SuppressWarnings("unchecked")
<T> T getConfigurer(Class<T> type) {
return (T) this.configurers.get(type);
}
private <T extends AbstractOAuth2Configurer> void addConfigurer(Class<T> configurerType, T configurer) {
this.configurers.put(configurerType, configurer);
}
}

10
oauth2-authorization-server/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/authorization/OidcTests.java

@ -186,6 +186,16 @@ public class OidcTests { @@ -186,6 +186,16 @@ public class OidcTests {
.andExpect(jsonPath("issuer").value(ISSUER_URL));
}
// gh-632
@Test
public void requestWhenConfigurationRequestAndUserAuthenticatedThenReturnConfigurationResponse() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
this.mvc.perform(get(DEFAULT_OIDC_PROVIDER_CONFIGURATION_ENDPOINT_URI)
.with(user("user")))
.andExpect(status().is2xxSuccessful());
}
@Test
public void loadContextWhenIssuerNotValidUrlThenThrowException() {
assertThatThrownBy(

Loading…
Cancel
Save