Переглянути джерело

Polish RoleHierarchy Bean Usage

Issue gh-12783
DerChris173 1 рік тому
батько
коміт
e6bea1cfa1

+ 2 - 4
config/src/main/java/org/springframework/security/config/annotation/method/configuration/Jsr250MethodSecurityConfiguration.java

@@ -22,7 +22,6 @@ import org.aopalliance.intercept.MethodInvocation;
 
 import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Role;
@@ -53,11 +52,10 @@ final class Jsr250MethodSecurityConfiguration {
 	static MethodInterceptor jsr250AuthorizationMethodInterceptor(
 			ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
 			ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
-			ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
+			ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider) {
 		Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
 		AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
-		RoleHierarchy roleHierarchy = (context.getBeanNamesForType(RoleHierarchy.class).length > 0)
-				? context.getBean(RoleHierarchy.class) : new NullRoleHierarchy();
+		RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
 		authoritiesAuthorizationManager.setRoleHierarchy(roleHierarchy);
 		jsr250.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager);
 		defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));

+ 23 - 18
config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java

@@ -65,11 +65,12 @@ final class PrePostMethodSecurityConfiguration {
 	static MethodInterceptor preFilterAuthorizationMethodInterceptor(
 			ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
 			ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
-			ObjectProvider<SecurityContextHolderStrategy> strategyProvider, ApplicationContext context) {
+			ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
+			ObjectProvider<RoleHierarchy> roleHierarchyProvider, ApplicationContext context) {
 		PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor();
 		strategyProvider.ifAvailable(preFilter::setSecurityContextHolderStrategy);
-		preFilter.setExpressionHandler(
-				new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
+		preFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
+				defaultsProvider, roleHierarchyProvider, context));
 		return preFilter;
 	}
 
@@ -80,10 +81,11 @@ final class PrePostMethodSecurityConfiguration {
 			ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
 			ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
 			ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
-			ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
+			ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
+			ApplicationContext context) {
 		PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
-		manager.setExpressionHandler(
-				new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
+		manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
+				defaultsProvider, roleHierarchyProvider, context));
 		AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
 			.preAuthorize(manager(manager, registryProvider));
 		strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
@@ -98,10 +100,11 @@ final class PrePostMethodSecurityConfiguration {
 			ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
 			ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
 			ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
-			ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
+			ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
+			ApplicationContext context) {
 		PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
-		manager.setExpressionHandler(
-				new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
+		manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
+				defaultsProvider, roleHierarchyProvider, context));
 		AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
 			.postAuthorize(manager(manager, registryProvider));
 		strategyProvider.ifAvailable(postAuthorize::setSecurityContextHolderStrategy);
@@ -114,19 +117,20 @@ final class PrePostMethodSecurityConfiguration {
 	static MethodInterceptor postFilterAuthorizationMethodInterceptor(
 			ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
 			ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
-			ObjectProvider<SecurityContextHolderStrategy> strategyProvider, ApplicationContext context) {
+			ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
+			ObjectProvider<RoleHierarchy> roleHierarchyProvider, ApplicationContext context) {
 		PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor();
 		strategyProvider.ifAvailable(postFilter::setSecurityContextHolderStrategy);
-		postFilter.setExpressionHandler(
-				new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider, defaultsProvider, context));
+		postFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
+				defaultsProvider, roleHierarchyProvider, context));
 		return postFilter;
 	}
 
 	private static MethodSecurityExpressionHandler defaultExpressionHandler(
-			ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext context) {
+			ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
+			ObjectProvider<RoleHierarchy> roleHierarchyProvider, ApplicationContext context) {
 		DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
-		RoleHierarchy roleHierarchy = (context.getBeanNamesForType(RoleHierarchy.class).length > 0)
-				? context.getBean(RoleHierarchy.class) : new NullRoleHierarchy();
+		RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
 		handler.setRoleHierarchy(roleHierarchy);
 		defaultsProvider.ifAvailable((d) -> handler.setDefaultRolePrefix(d.getRolePrefix()));
 		handler.setApplicationContext(context);
@@ -144,9 +148,10 @@ final class PrePostMethodSecurityConfiguration {
 
 		private DeferringMethodSecurityExpressionHandler(
 				ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
-				ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext applicationContext) {
-			this.expressionHandler = SingletonSupplier.of(() -> expressionHandlerProvider
-				.getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, applicationContext)));
+				ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
+				ObjectProvider<RoleHierarchy> roleHierarchyProvider, ApplicationContext applicationContext) {
+			this.expressionHandler = SingletonSupplier.of(() -> expressionHandlerProvider.getIfAvailable(
+					() -> defaultExpressionHandler(defaultsProvider, roleHierarchyProvider, applicationContext)));
 		}
 
 		@Override

+ 2 - 4
config/src/main/java/org/springframework/security/config/annotation/method/configuration/SecuredMethodSecurityConfiguration.java

@@ -22,7 +22,6 @@ import org.aopalliance.intercept.MethodInvocation;
 
 import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Role;
@@ -52,11 +51,10 @@ final class SecuredMethodSecurityConfiguration {
 	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 	static MethodInterceptor securedAuthorizationMethodInterceptor(
 			ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
-			ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
+			ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider) {
 		SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
 		AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
-		RoleHierarchy roleHierarchy = (context.getBeanNamesForType(RoleHierarchy.class).length > 0)
-				? context.getBean(RoleHierarchy.class) : new NullRoleHierarchy();
+		RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
 		authoritiesAuthorizationManager.setRoleHierarchy(roleHierarchy);
 		secured.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager);
 		SecurityContextHolderStrategy strategy = strategyProvider

+ 5 - 2
config/src/test/java/org/springframework/security/config/annotation/method/configuration/MethodSecurityService.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 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.
@@ -50,9 +50,12 @@ public interface MethodSecurityService {
 	@PermitAll
 	String jsr250PermitAll();
 
-	@RolesAllowed({ "ADMIN", "USER" })
+	@RolesAllowed("ADMIN")
 	String jsr250RolesAllowed();
 
+	@RolesAllowed("USER")
+	String jsr250RolesAllowedUser();
+
 	@Secured({ "ROLE_USER", "RUN_AS_SUPER" })
 	Authentication runAs();
 

+ 6 - 1
config/src/test/java/org/springframework/security/config/annotation/method/configuration/MethodSecurityServiceImpl.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 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.
@@ -56,6 +56,11 @@ public class MethodSecurityServiceImpl implements MethodSecurityService {
 		return null;
 	}
 
+	@Override
+	public String jsr250RolesAllowedUser() {
+		return null;
+	}
+
 	@Override
 	public Authentication runAs() {
 		return SecurityContextHolder.getContext().getAuthentication();

+ 6 - 6
config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java

@@ -453,9 +453,9 @@ public class PrePostMethodSecurityConfigurationTests {
 	@Test
 	public void methodSecurityAdminWhenRoleHierarchyBeanAvailableThenUses() {
 		this.spring.register(RoleHierarchyConfig.class, MethodSecurityServiceConfig.class).autowire();
-		this.methodSecurityService.preAuthorizeAdmin();
-		this.methodSecurityService.secured();
-		this.methodSecurityService.jsr250RolesAllowed();
+		this.methodSecurityService.preAuthorizeUser();
+		this.methodSecurityService.securedUser();
+		this.methodSecurityService.jsr250RolesAllowedUser();
 	}
 
 	@WithMockUser
@@ -464,7 +464,7 @@ public class PrePostMethodSecurityConfigurationTests {
 		this.spring.register(RoleHierarchyConfig.class, MethodSecurityServiceConfig.class).autowire();
 		this.methodSecurityService.preAuthorizeUser();
 		this.methodSecurityService.securedUser();
-		this.methodSecurityService.jsr250RolesAllowed();
+		this.methodSecurityService.jsr250RolesAllowedUser();
 	}
 
 	private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
@@ -652,9 +652,9 @@ public class PrePostMethodSecurityConfigurationTests {
 	static class RoleHierarchyConfig {
 
 		@Bean
-		RoleHierarchy roleHierarchy() {
+		static RoleHierarchy roleHierarchy() {
 			RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
-			roleHierarchyImpl.setHierarchy("ADMIN > USER");
+			roleHierarchyImpl.setHierarchy("ROLE_ADMIN > ROLE_USER");
 			return roleHierarchyImpl;
 		}