mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-26 13:53:14 +00:00
Use available RoleHierachy Bean for MethodSecurity Config
Closes gh-12783
This commit is contained in:
parent
bb6b55aca3
commit
b76f7c029d
@ -22,9 +22,13 @@ import org.aopalliance.intercept.MethodInvocation;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
||||||
@ -49,8 +53,13 @@ final class Jsr250MethodSecurityConfiguration {
|
|||||||
static MethodInterceptor jsr250AuthorizationMethodInterceptor(
|
static MethodInterceptor jsr250AuthorizationMethodInterceptor(
|
||||||
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider) {
|
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
|
||||||
Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
|
Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
|
||||||
|
AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
|
||||||
|
RoleHierarchy roleHierarchy = (context.getBeanNamesForType(RoleHierarchy.class).length > 0)
|
||||||
|
? context.getBean(RoleHierarchy.class) : new NullRoleHierarchy();
|
||||||
|
authoritiesAuthorizationManager.setRoleHierarchy(roleHierarchy);
|
||||||
|
jsr250.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager);
|
||||||
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
|
defaultsProvider.ifAvailable((d) -> jsr250.setRolePrefix(d.getRolePrefix()));
|
||||||
SecurityContextHolderStrategy strategy = strategyProvider
|
SecurityContextHolderStrategy strategy = strategyProvider
|
||||||
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
||||||
|
@ -33,6 +33,8 @@ import org.springframework.expression.Expression;
|
|||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerAfterMethodInterceptor;
|
||||||
@ -123,6 +125,9 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
private static MethodSecurityExpressionHandler defaultExpressionHandler(
|
private static MethodSecurityExpressionHandler defaultExpressionHandler(
|
||||||
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext context) {
|
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider, ApplicationContext context) {
|
||||||
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
|
DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
|
||||||
|
RoleHierarchy roleHierarchy = (context.getBeanNamesForType(RoleHierarchy.class).length > 0)
|
||||||
|
? context.getBean(RoleHierarchy.class) : new NullRoleHierarchy();
|
||||||
|
handler.setRoleHierarchy(roleHierarchy);
|
||||||
defaultsProvider.ifAvailable((d) -> handler.setDefaultRolePrefix(d.getRolePrefix()));
|
defaultsProvider.ifAvailable((d) -> handler.setDefaultRolePrefix(d.getRolePrefix()));
|
||||||
handler.setApplicationContext(context);
|
handler.setApplicationContext(context);
|
||||||
return handler;
|
return handler;
|
||||||
|
@ -22,10 +22,14 @@ import org.aopalliance.intercept.MethodInvocation;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.SecuredAuthorizationManager;
|
import org.springframework.security.authorization.method.SecuredAuthorizationManager;
|
||||||
@ -48,8 +52,13 @@ final class SecuredMethodSecurityConfiguration {
|
|||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
static MethodInterceptor securedAuthorizationMethodInterceptor(
|
static MethodInterceptor securedAuthorizationMethodInterceptor(
|
||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider) {
|
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
|
||||||
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
||||||
|
AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
|
||||||
|
RoleHierarchy roleHierarchy = (context.getBeanNamesForType(RoleHierarchy.class).length > 0)
|
||||||
|
? context.getBean(RoleHierarchy.class) : new NullRoleHierarchy();
|
||||||
|
authoritiesAuthorizationManager.setRoleHierarchy(roleHierarchy);
|
||||||
|
secured.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager);
|
||||||
SecurityContextHolderStrategy strategy = strategyProvider
|
SecurityContextHolderStrategy strategy = strategyProvider
|
||||||
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
.getIfAvailable(SecurityContextHolder::getContextHolderStrategy);
|
||||||
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(
|
AuthorizationManager<MethodInvocation> manager = new DeferringObservationAuthorizationManager<>(
|
||||||
|
@ -50,7 +50,7 @@ public interface MethodSecurityService {
|
|||||||
@PermitAll
|
@PermitAll
|
||||||
String jsr250PermitAll();
|
String jsr250PermitAll();
|
||||||
|
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed({ "ADMIN", "USER" })
|
||||||
String jsr250RolesAllowed();
|
String jsr250RolesAllowed();
|
||||||
|
|
||||||
@Secured({ "ROLE_USER", "RUN_AS_SUPER" })
|
@Secured({ "ROLE_USER", "RUN_AS_SUPER" })
|
||||||
@ -68,6 +68,9 @@ public interface MethodSecurityService {
|
|||||||
@PreAuthorize("hasRole('ADMIN')")
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
void preAuthorizeAdmin();
|
void preAuthorizeAdmin();
|
||||||
|
|
||||||
|
@PreAuthorize("hasRole('USER')")
|
||||||
|
void preAuthorizeUser();
|
||||||
|
|
||||||
@PreAuthorize("hasPermission(#object,'read')")
|
@PreAuthorize("hasPermission(#object,'read')")
|
||||||
String hasPermission(String object);
|
String hasPermission(String object);
|
||||||
|
|
||||||
|
@ -73,6 +73,10 @@ public class MethodSecurityServiceImpl implements MethodSecurityService {
|
|||||||
public void preAuthorizeAdmin() {
|
public void preAuthorizeAdmin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preAuthorizeUser() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String preAuthorizePermitAll() {
|
public String preAuthorizePermitAll() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -46,6 +46,8 @@ import org.springframework.security.access.annotation.ExpressionProtectedBusines
|
|||||||
import org.springframework.security.access.annotation.Jsr250BusinessServiceImpl;
|
import org.springframework.security.access.annotation.Jsr250BusinessServiceImpl;
|
||||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
@ -447,6 +449,24 @@ public class PrePostMethodSecurityConfigurationTests {
|
|||||||
.autowire();
|
.autowire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WithMockUser(roles = "ADMIN")
|
||||||
|
@Test
|
||||||
|
public void methodSecurityAdminWhenRoleHierarchyBeanAvailableThenUses() {
|
||||||
|
this.spring.register(RoleHierarchyConfig.class, MethodSecurityServiceConfig.class).autowire();
|
||||||
|
this.methodSecurityService.preAuthorizeAdmin();
|
||||||
|
this.methodSecurityService.secured();
|
||||||
|
this.methodSecurityService.jsr250RolesAllowed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithMockUser
|
||||||
|
@Test
|
||||||
|
public void methodSecurityUserWhenRoleHierarchyBeanAvailableThenUses() {
|
||||||
|
this.spring.register(RoleHierarchyConfig.class, MethodSecurityServiceConfig.class).autowire();
|
||||||
|
this.methodSecurityService.preAuthorizeUser();
|
||||||
|
this.methodSecurityService.securedUser();
|
||||||
|
this.methodSecurityService.jsr250RolesAllowed();
|
||||||
|
}
|
||||||
|
|
||||||
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
|
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
|
||||||
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
|
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
|
||||||
}
|
}
|
||||||
@ -627,4 +647,17 @@ public class PrePostMethodSecurityConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableMethodSecurity(jsr250Enabled = true, securedEnabled = true)
|
||||||
|
static class RoleHierarchyConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RoleHierarchy roleHierarchy() {
|
||||||
|
RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
|
||||||
|
roleHierarchyImpl.setHierarchy("ADMIN > USER");
|
||||||
|
return roleHierarchyImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user