浏览代码

Merge remote-tracking branch 'origin/5.8.x'

Josh Cummings 2 年之前
父节点
当前提交
72a46ddd31

+ 17 - 1
config/src/main/java/org/springframework/security/config/http/AuthorizationFilterParser.java

@@ -49,6 +49,8 @@ class AuthorizationFilterParser implements BeanDefinitionParser {
 
 
 	private static final String ATT_USE_EXPRESSIONS = "use-expressions";
 	private static final String ATT_USE_EXPRESSIONS = "use-expressions";
 
 
+	private static final String ATT_ACCESS_DECISION_MANAGER_REF = "access-decision-manager-ref";
+
 	private static final String ATT_HTTP_METHOD = "method";
 	private static final String ATT_HTTP_METHOD = "method";
 
 
 	private static final String ATT_PATTERN = "pattern";
 	private static final String ATT_PATTERN = "pattern";
@@ -59,6 +61,12 @@ class AuthorizationFilterParser implements BeanDefinitionParser {
 
 
 	private String authorizationManagerRef;
 	private String authorizationManagerRef;
 
 
+	private final BeanMetadataElement securityContextHolderStrategy;
+
+	AuthorizationFilterParser(BeanMetadataElement securityContextHolderStrategy) {
+		this.securityContextHolderStrategy = securityContextHolderStrategy;
+	}
+
 	@Override
 	@Override
 	public BeanDefinition parse(Element element, ParserContext parserContext) {
 	public BeanDefinition parse(Element element, ParserContext parserContext) {
 		if (!isUseExpressions(element)) {
 		if (!isUseExpressions(element)) {
@@ -66,10 +74,16 @@ class AuthorizationFilterParser implements BeanDefinitionParser {
 					element);
 					element);
 			return null;
 			return null;
 		}
 		}
+		if (StringUtils.hasText(element.getAttribute(ATT_ACCESS_DECISION_MANAGER_REF))) {
+			parserContext.getReaderContext().error(
+					"AuthorizationManager cannot be used in conjunction with `access-decision-manager-ref`", element);
+			return null;
+		}
 		this.authorizationManagerRef = createAuthorizationManager(element, parserContext);
 		this.authorizationManagerRef = createAuthorizationManager(element, parserContext);
 		BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(AuthorizationFilter.class);
 		BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(AuthorizationFilter.class);
 		filterBuilder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
 		filterBuilder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
 		BeanDefinition filter = filterBuilder.addConstructorArgReference(this.authorizationManagerRef)
 		BeanDefinition filter = filterBuilder.addConstructorArgReference(this.authorizationManagerRef)
+				.addPropertyValue("securityContextHolderStrategy", this.securityContextHolderStrategy)
 				.getBeanDefinition();
 				.getBeanDefinition();
 		String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
 		String id = element.getAttribute(AbstractBeanDefinitionParser.ID_ATTRIBUTE);
 		if (StringUtils.hasText(id)) {
 		if (StringUtils.hasText(id)) {
@@ -171,7 +185,9 @@ class AuthorizationFilterParser implements BeanDefinitionParser {
 
 
 		@Override
 		@Override
 		public DefaultHttpSecurityExpressionHandler getBean() {
 		public DefaultHttpSecurityExpressionHandler getBean() {
-			this.handler.setDefaultRolePrefix(this.rolePrefix);
+			if (this.rolePrefix != null) {
+				this.handler.setDefaultRolePrefix(this.rolePrefix);
+			}
 			return this.handler;
 			return this.handler;
 		}
 		}
 
 

+ 1 - 1
config/src/main/java/org/springframework/security/config/http/HttpConfigurationBuilder.java

@@ -729,7 +729,7 @@ class HttpConfigurationBuilder {
 	}
 	}
 
 
 	private void createAuthorizationFilter() {
 	private void createAuthorizationFilter() {
-		AuthorizationFilterParser authorizationFilterParser = new AuthorizationFilterParser();
+		AuthorizationFilterParser authorizationFilterParser = new AuthorizationFilterParser(this.holderStrategyRef);
 		BeanDefinition fsiBean = authorizationFilterParser.parse(this.httpElt, this.pc);
 		BeanDefinition fsiBean = authorizationFilterParser.parse(this.httpElt, this.pc);
 		String fsiId = this.pc.getReaderContext().generateBeanName(fsiBean);
 		String fsiId = this.pc.getReaderContext().generateBeanName(fsiBean);
 		this.pc.registerBeanComponent(new BeanComponentDefinition(fsiBean, fsiId));
 		this.pc.registerBeanComponent(new BeanComponentDefinition(fsiBean, fsiId));

+ 3 - 3
config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java

@@ -1356,11 +1356,10 @@ public class OAuth2ResourceServerConfigurerTests {
 	}
 	}
 
 
 	@Test
 	@Test
-	public void getWhenCustomAuthenticationConverterThenConverts() throws Exception {
+	public void getWhenCustomAuthenticationConverterThenUsed() throws Exception {
 		this.spring.register(RestOperationsConfig.class, OpaqueTokenAuthenticationConverterConfig.class,
 		this.spring.register(RestOperationsConfig.class, OpaqueTokenAuthenticationConverterConfig.class,
 				BasicController.class).autowire();
 				BasicController.class).autowire();
-		OpaqueTokenAuthenticationConverter authenticationConverter = this.spring.getContext()
-				.getBean(OpaqueTokenAuthenticationConverter.class);
+		OpaqueTokenAuthenticationConverter authenticationConverter = bean(OpaqueTokenAuthenticationConverter.class);
 		given(authenticationConverter.convert(anyString(), any(OAuth2AuthenticatedPrincipal.class)))
 		given(authenticationConverter.convert(anyString(), any(OAuth2AuthenticatedPrincipal.class)))
 				.willReturn(new TestingAuthenticationToken("jdoe", null, Collections.emptyList()));
 				.willReturn(new TestingAuthenticationToken("jdoe", null, Collections.emptyList()));
 		mockRestOperations(json("Active"));
 		mockRestOperations(json("Active"));
@@ -1369,6 +1368,7 @@ public class OAuth2ResourceServerConfigurerTests {
 				.andExpect(status().isOk())
 				.andExpect(status().isOk())
 				.andExpect(content().string("jdoe"));
 				.andExpect(content().string("jdoe"));
 		// @formatter:on
 		// @formatter:on
+		verify(authenticationConverter).convert(any(), any());
 	}
 	}
 
 
 	private static <T> void registerMockBean(GenericApplicationContext context, String name, Class<T> clazz) {
 	private static <T> void registerMockBean(GenericApplicationContext context, String name, Class<T> clazz) {

+ 5 - 43
config/src/test/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests.java

@@ -23,7 +23,6 @@ import java.security.interfaces.RSAPublicKey;
 import java.time.Clock;
 import java.time.Clock;
 import java.time.Instant;
 import java.time.Instant;
 import java.time.ZoneId;
 import java.time.ZoneId;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
@@ -67,16 +66,14 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.MediaType;
 import org.springframework.http.RequestEntity;
 import org.springframework.http.RequestEntity;
 import org.springframework.http.ResponseEntity;
 import org.springframework.http.ResponseEntity;
-import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationManagerResolver;
 import org.springframework.security.authentication.AuthenticationManagerResolver;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.TestingAuthenticationToken;
 import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.JwtBeanDefinitionParser;
 import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.JwtBeanDefinitionParser;
 import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser;
 import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser;
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContext;
 import org.springframework.security.config.test.SpringTestContextExtension;
 import org.springframework.security.config.test.SpringTestContextExtension;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
+import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2TokenValidator;
 import org.springframework.security.oauth2.core.OAuth2TokenValidator;
 import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
 import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
@@ -654,13 +651,13 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
 		this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueTokenAndAuthenticationConverter"))
 		this.spring.configLocations(xml("OpaqueTokenRestOperations"), xml("OpaqueTokenAndAuthenticationConverter"))
 				.autowire();
 				.autowire();
 		mockRestOperations(json("Active"));
 		mockRestOperations(json("Active"));
+		OpaqueTokenAuthenticationConverter converter = bean(OpaqueTokenAuthenticationConverter.class);
+		given(converter.convert(any(), any())).willReturn(new TestingAuthenticationToken("user", "pass", "app"));
 		// @formatter:off
 		// @formatter:off
 		this.mvc.perform(get("/authenticated").header("Authorization", "Bearer token"))
 		this.mvc.perform(get("/authenticated").header("Authorization", "Bearer token"))
 				.andExpect(status().isNotFound());
 				.andExpect(status().isNotFound());
-
-		this.mvc.perform(get("/authenticated").header("Authorization", "Bearer invalidToken"))
-				.andExpect(status().isUnauthorized());
 		// @formatter:on
 		// @formatter:on
+		verify(converter).convert(any(), any());
 	}
 	}
 
 
 	@Test
 	@Test
@@ -1097,39 +1094,4 @@ public class OAuth2ResourceServerBeanDefinitionParserTests {
 
 
 	}
 	}
 
 
-	public static class TestAuthentication extends AbstractAuthenticationToken {
-
-		private final String introspectedToken;
-
-		public TestAuthentication(String introspectedToken, Collection<? extends GrantedAuthority> authorities) {
-			super(authorities);
-			this.introspectedToken = introspectedToken;
-		}
-
-		@Override
-		public Object getCredentials() {
-			return this.introspectedToken;
-		}
-
-		@Override
-		public Object getPrincipal() {
-			return this.introspectedToken;
-		}
-
-		@Override
-		public boolean isAuthenticated() {
-			return "token".equals(this.introspectedToken);
-		}
-
-	}
-
-	public static class TestOpaqueTokenAuthenticationConverter implements OpaqueTokenAuthenticationConverter {
-
-		@Override
-		public Authentication convert(String introspectedToken, OAuth2AuthenticatedPrincipal authenticatedPrincipal) {
-			return new TestAuthentication(introspectedToken, Collections.emptyList());
-		}
-
-	}
-
 }
 }

+ 2 - 1
config/src/test/resources/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests-OpaqueTokenAndAuthenticationConverter.xml

@@ -22,7 +22,8 @@
 		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
 		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
 
 
 	<b:bean name="authentication-converter"
 	<b:bean name="authentication-converter"
-			class="org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParserTests$TestOpaqueTokenAuthenticationConverter">
+			class="org.mockito.Mockito" factory-method="mock">
+		<b:constructor-arg value="org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenAuthenticationConverter"/>
 	</b:bean>
 	</b:bean>
 
 
 	<http>
 	<http>

+ 1 - 1
web/src/main/java/org/springframework/security/web/access/expression/DefaultHttpSecurityExpressionHandler.java

@@ -90,7 +90,7 @@ public class DefaultHttpSecurityExpressionHandler extends AbstractSecurityExpres
 	 * "ROLE_".
 	 * "ROLE_".
 	 */
 	 */
 	public void setDefaultRolePrefix(String defaultRolePrefix) {
 	public void setDefaultRolePrefix(String defaultRolePrefix) {
-		Assert.hasText(defaultRolePrefix, "defaultRolePrefix cannot be empty");
+		Assert.notNull(defaultRolePrefix, "defaultRolePrefix cannot be null");
 		this.defaultRolePrefix = defaultRolePrefix;
 		this.defaultRolePrefix = defaultRolePrefix;
 	}
 	}