Add SecurityContextHolderStrategy XML Configuration for OAuth2

Issue gh-11061
This commit is contained in:
Josh Cummings
2022-06-24 13:24:24 -06:00
parent 1d22316574
commit 652c35db2f
10 changed files with 195 additions and 23 deletions

View File

@@ -224,7 +224,8 @@ public class OAuth2ResourceServerConfigurerTests {
@Test
public void getWhenCustomSecurityContextHolderStrategyThenUses() throws Exception {
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class, SecurityContextChangedListenerConfig.class).autowire();
this.spring.register(RestOperationsConfig.class, DefaultConfig.class, BasicController.class,
SecurityContextChangedListenerConfig.class).autowire();
mockRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
@@ -78,6 +79,7 @@ import org.springframework.web.bind.annotation.RestController;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -137,6 +139,9 @@ public class OAuth2LoginBeanDefinitionParserTests {
@Autowired(required = false)
private RequestCache requestCache;
@Autowired(required = false)
private SecurityContextHolderStrategy securityContextHolderStrategy;
@Autowired
private MockMvc mvc;
@@ -472,6 +477,28 @@ public class OAuth2LoginBeanDefinitionParserTests {
verify(this.authorizedClientService).saveAuthorizedClient(any(), any());
}
@Test
public void requestWhenCustomSecurityContextHolderStrategyThenCalled() throws Exception {
this.spring.configLocations(this.xml("WithCustomSecurityContextHolderStrategy")).autowire();
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().build();
given(this.clientRegistrationRepository.findByRegistrationId(any())).willReturn(clientRegistration);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request()
.attributes(attributes).build();
given(this.authorizationRequestRepository.removeAuthorizationRequest(any(), any()))
.willReturn(authorizationRequest);
OAuth2AccessTokenResponse accessTokenResponse = TestOAuth2AccessTokenResponses.accessTokenResponse().build();
given(this.accessTokenResponseClient.getTokenResponse(any())).willReturn(accessTokenResponse);
OAuth2User oauth2User = TestOAuth2Users.create();
given(this.oauth2UserService.loadUser(any())).willReturn(oauth2User);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", "code123");
params.add("state", authorizationRequest.getState());
this.mvc.perform(get("/login/oauth2/code/" + clientRegistration.getRegistrationId()).params(params));
verify(this.securityContextHolderStrategy, atLeastOnce()).getContext();
}
@WithMockUser
@Test
public void requestWhenAuthorizedClientFoundThenMethodArgumentResolved() throws Exception {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -73,6 +74,7 @@ import org.springframework.security.config.http.OAuth2ResourceServerBeanDefiniti
import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
@@ -105,6 +107,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -144,6 +147,20 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
// @formatter:on
}
@Test
public void getWhenCustomSecurityContextHolderStrategyThenUses() throws Exception {
this.spring.configLocations(xml("JwtRestOperations"), xml("JwtCustomSecurityContextHolderStrategy")).autowire();
mockRestOperations(jwks("Default"));
String token = this.token("ValidNoScopes");
// @formatter:off
this.mvc.perform(get("/").header("Authorization", "Bearer " + token))
.andExpect(status().isNotFound());
// @formatter:on
SecurityContextHolderStrategy securityContextHolderStrategy = this.spring.getContext()
.getBean(SecurityContextHolderStrategy.class);
verify(securityContextHolderStrategy, atLeastOnce()).getContext();
}
@Test
public void getWhenUsingJwkSetUriThenAcceptsRequest() throws Exception {
this.spring.configLocations(xml("WebServer"), xml("JwkSetUri")).autowire();
@@ -505,7 +522,8 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void getBearerTokenResolverWhenNoResolverSpecifiedThenTheDefaultIsUsed() {
OAuth2ResourceServerBeanDefinitionParser oauth2 = new OAuth2ResourceServerBeanDefinitionParser(
mock(BeanReference.class), mock(List.class), mock(Map.class), mock(Map.class), mock(List.class));
mock(BeanReference.class), mock(List.class), mock(Map.class), mock(Map.class), mock(List.class),
mock(BeanMetadataElement.class));
assertThat(oauth2.getBearerTokenResolver(mock(Element.class))).isInstanceOf(RootBeanDefinition.class);
}
@@ -800,7 +818,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void validateConfigurationWhenMoreThanOneResourceServerModeThenError() {
OAuth2ResourceServerBeanDefinitionParser parser = new OAuth2ResourceServerBeanDefinitionParser(null, null, null,
null, null);
null, null, null);
Element element = mock(Element.class);
given(element.hasAttribute(OAuth2ResourceServerBeanDefinitionParser.AUTHENTICATION_MANAGER_RESOLVER_REF))
.willReturn(true);
@@ -816,7 +834,7 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
@Test
public void validateConfigurationWhenNoResourceServerModeThenError() {
OAuth2ResourceServerBeanDefinitionParser parser = new OAuth2ResourceServerBeanDefinitionParser(null, null, null,
null, null);
null, null, null);
Element element = mock(Element.class);
given(element.hasAttribute(OAuth2ResourceServerBeanDefinitionParser.AUTHENTICATION_MANAGER_RESOLVER_REF))
.willReturn(false);