mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-28 14:52:24 +00:00
Add order offset to @EnableMethodSecurity
Closes gh-13214
This commit is contained in:
parent
c19f3d9d06
commit
99218db84a
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -87,4 +87,14 @@ public @interface EnableMethodSecurity {
|
|||||||
*/
|
*/
|
||||||
AdviceMode mode() default AdviceMode.PROXY;
|
AdviceMode mode() default AdviceMode.PROXY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate additional offset in the ordering of the execution of the security
|
||||||
|
* interceptors when multiple advices are applied at a specific joinpoint. I.e.,
|
||||||
|
* precedence of each security interceptor enabled by this annotation will be
|
||||||
|
* calculated as sum of its default precedence and offset. The default is 0.
|
||||||
|
* @return the offset in the order the security advisor should be applied
|
||||||
|
* @since 6.3
|
||||||
|
*/
|
||||||
|
int offset() default 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@ import org.springframework.beans.factory.ObjectProvider;
|
|||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
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.ImportAware;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
|
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
|
||||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
|
import org.springframework.security.authorization.AuthoritiesAuthorizationManager;
|
||||||
@ -45,14 +47,17 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
final class Jsr250MethodSecurityConfiguration {
|
final class Jsr250MethodSecurityConfiguration implements ImportAware {
|
||||||
|
|
||||||
|
private int interceptorOrderOffset;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
static MethodInterceptor jsr250AuthorizationMethodInterceptor(
|
static MethodInterceptor jsr250AuthorizationMethodInterceptor(
|
||||||
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider) {
|
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
|
||||||
|
Jsr250MethodSecurityConfiguration configuration) {
|
||||||
Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
|
Jsr250AuthorizationManager jsr250 = new Jsr250AuthorizationManager();
|
||||||
AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
|
AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
|
||||||
RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
|
RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
|
||||||
@ -65,8 +70,15 @@ final class Jsr250MethodSecurityConfiguration {
|
|||||||
registryProvider, jsr250);
|
registryProvider, jsr250);
|
||||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||||
.jsr250(manager);
|
.jsr250(manager);
|
||||||
|
interceptor.setOrder(interceptor.getOrder() + configuration.interceptorOrderOffset);
|
||||||
interceptor.setSecurityContextHolderStrategy(strategy);
|
interceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||||
|
EnableMethodSecurity annotation = importMetadata.getAnnotations().get(EnableMethodSecurity.class).synthesize();
|
||||||
|
this.interceptorOrderOffset = annotation.offset();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,9 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||||||
import org.springframework.context.ApplicationContext;
|
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.ImportAware;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
@ -58,7 +60,9 @@ import org.springframework.util.function.SingletonSupplier;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
final class PrePostMethodSecurityConfiguration {
|
final class PrePostMethodSecurityConfiguration implements ImportAware {
|
||||||
|
|
||||||
|
private int interceptorOrderOffset;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
@ -66,8 +70,10 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
||||||
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
|
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
|
||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<RoleHierarchy> roleHierarchyProvider, ApplicationContext context) {
|
ObjectProvider<RoleHierarchy> roleHierarchyProvider, PrePostMethodSecurityConfiguration configuration,
|
||||||
|
ApplicationContext context) {
|
||||||
PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor();
|
PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor();
|
||||||
|
preFilter.setOrder(preFilter.getOrder() + configuration.interceptorOrderOffset);
|
||||||
strategyProvider.ifAvailable(preFilter::setSecurityContextHolderStrategy);
|
strategyProvider.ifAvailable(preFilter::setSecurityContextHolderStrategy);
|
||||||
preFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
preFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
||||||
defaultsProvider, roleHierarchyProvider, context));
|
defaultsProvider, roleHierarchyProvider, context));
|
||||||
@ -82,12 +88,13 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
|
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
|
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
|
||||||
ApplicationContext context) {
|
PrePostMethodSecurityConfiguration configuration, ApplicationContext context) {
|
||||||
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
|
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
|
||||||
manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
||||||
defaultsProvider, roleHierarchyProvider, context));
|
defaultsProvider, roleHierarchyProvider, context));
|
||||||
AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
|
AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
|
||||||
.preAuthorize(manager(manager, registryProvider));
|
.preAuthorize(manager(manager, registryProvider));
|
||||||
|
preAuthorize.setOrder(preAuthorize.getOrder() + configuration.interceptorOrderOffset);
|
||||||
strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
|
strategyProvider.ifAvailable(preAuthorize::setSecurityContextHolderStrategy);
|
||||||
eventPublisherProvider.ifAvailable(preAuthorize::setAuthorizationEventPublisher);
|
eventPublisherProvider.ifAvailable(preAuthorize::setAuthorizationEventPublisher);
|
||||||
return preAuthorize;
|
return preAuthorize;
|
||||||
@ -101,12 +108,13 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
|
ObjectProvider<AuthorizationEventPublisher> eventPublisherProvider,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
|
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
|
||||||
ApplicationContext context) {
|
PrePostMethodSecurityConfiguration configuration, ApplicationContext context) {
|
||||||
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
|
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
|
||||||
manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
manager.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
||||||
defaultsProvider, roleHierarchyProvider, context));
|
defaultsProvider, roleHierarchyProvider, context));
|
||||||
AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
|
AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
|
||||||
.postAuthorize(manager(manager, registryProvider));
|
.postAuthorize(manager(manager, registryProvider));
|
||||||
|
postAuthorize.setOrder(postAuthorize.getOrder() + configuration.interceptorOrderOffset);
|
||||||
strategyProvider.ifAvailable(postAuthorize::setSecurityContextHolderStrategy);
|
strategyProvider.ifAvailable(postAuthorize::setSecurityContextHolderStrategy);
|
||||||
eventPublisherProvider.ifAvailable(postAuthorize::setAuthorizationEventPublisher);
|
eventPublisherProvider.ifAvailable(postAuthorize::setAuthorizationEventPublisher);
|
||||||
return postAuthorize;
|
return postAuthorize;
|
||||||
@ -118,8 +126,10 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
ObjectProvider<GrantedAuthorityDefaults> defaultsProvider,
|
||||||
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
|
ObjectProvider<MethodSecurityExpressionHandler> expressionHandlerProvider,
|
||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<RoleHierarchy> roleHierarchyProvider, ApplicationContext context) {
|
ObjectProvider<RoleHierarchy> roleHierarchyProvider, PrePostMethodSecurityConfiguration configuration,
|
||||||
|
ApplicationContext context) {
|
||||||
PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor();
|
PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor();
|
||||||
|
postFilter.setOrder(postFilter.getOrder() + configuration.interceptorOrderOffset);
|
||||||
strategyProvider.ifAvailable(postFilter::setSecurityContextHolderStrategy);
|
strategyProvider.ifAvailable(postFilter::setSecurityContextHolderStrategy);
|
||||||
postFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
postFilter.setExpressionHandler(new DeferringMethodSecurityExpressionHandler(expressionHandlerProvider,
|
||||||
defaultsProvider, roleHierarchyProvider, context));
|
defaultsProvider, roleHierarchyProvider, context));
|
||||||
@ -142,6 +152,12 @@ final class PrePostMethodSecurityConfiguration {
|
|||||||
return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
|
return new DeferringObservationAuthorizationManager<>(registryProvider, delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||||
|
EnableMethodSecurity annotation = importMetadata.getAnnotations().get(EnableMethodSecurity.class).synthesize();
|
||||||
|
this.interceptorOrderOffset = annotation.offset();
|
||||||
|
}
|
||||||
|
|
||||||
private static final class DeferringMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler {
|
private static final class DeferringMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler {
|
||||||
|
|
||||||
private final Supplier<MethodSecurityExpressionHandler> expressionHandler;
|
private final Supplier<MethodSecurityExpressionHandler> expressionHandler;
|
||||||
|
@ -24,7 +24,9 @@ import org.springframework.beans.factory.ObjectProvider;
|
|||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
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.ImportAware;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
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.NullRoleHierarchy;
|
||||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
@ -45,13 +47,16 @@ import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
|||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
final class SecuredMethodSecurityConfiguration {
|
final class SecuredMethodSecurityConfiguration implements ImportAware {
|
||||||
|
|
||||||
|
private int interceptorOrderOffset;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
static MethodInterceptor securedAuthorizationMethodInterceptor(
|
static MethodInterceptor securedAuthorizationMethodInterceptor(
|
||||||
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
ObjectProvider<SecurityContextHolderStrategy> strategyProvider,
|
||||||
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider) {
|
ObjectProvider<ObservationRegistry> registryProvider, ObjectProvider<RoleHierarchy> roleHierarchyProvider,
|
||||||
|
SecuredMethodSecurityConfiguration configuration) {
|
||||||
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
SecuredAuthorizationManager secured = new SecuredAuthorizationManager();
|
||||||
AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
|
AuthoritiesAuthorizationManager authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager();
|
||||||
RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
|
RoleHierarchy roleHierarchy = roleHierarchyProvider.getIfAvailable(NullRoleHierarchy::new);
|
||||||
@ -63,8 +68,15 @@ final class SecuredMethodSecurityConfiguration {
|
|||||||
registryProvider, secured);
|
registryProvider, secured);
|
||||||
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||||
.secured(manager);
|
.secured(manager);
|
||||||
|
interceptor.setOrder(interceptor.getOrder() + configuration.interceptorOrderOffset);
|
||||||
interceptor.setSecurityContextHolderStrategy(strategy);
|
interceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||||
|
EnableMethodSecurity annotation = importMetadata.getAnnotations().get(EnableMethodSecurity.class).synthesize();
|
||||||
|
this.interceptorOrderOffset = annotation.offset();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,14 @@ public interface MethodSecurityService {
|
|||||||
@PostAuthorize("returnObject.size == 2")
|
@PostAuthorize("returnObject.size == 2")
|
||||||
List<String> manyAnnotations(List<String> array);
|
List<String> manyAnnotations(List<String> array);
|
||||||
|
|
||||||
|
@PreFilter("filterObject != 'DropOnPreFilter'")
|
||||||
|
@PreAuthorize("#list.remove('DropOnPreAuthorize')")
|
||||||
|
@Secured("ROLE_SECURED")
|
||||||
|
@RolesAllowed("JSR250")
|
||||||
|
@PostAuthorize("#list.remove('DropOnPostAuthorize')")
|
||||||
|
@PostFilter("filterObject != 'DropOnPostFilter'")
|
||||||
|
List<String> allAnnotations(List<String> list);
|
||||||
|
|
||||||
@RequireUserRole
|
@RequireUserRole
|
||||||
@RequireAdminRole
|
@RequireAdminRole
|
||||||
void repeatedAnnotations();
|
void repeatedAnnotations();
|
||||||
|
@ -117,6 +117,11 @@ public class MethodSecurityServiceImpl implements MethodSecurityService {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> allAnnotations(List<String> list) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void repeatedAnnotations() {
|
public void repeatedAnnotations() {
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
|||||||
import org.springframework.context.annotation.AdviceMode;
|
import org.springframework.context.annotation.AdviceMode;
|
||||||
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.Import;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
import org.springframework.core.annotation.AnnotationConfigurationException;
|
import org.springframework.core.annotation.AnnotationConfigurationException;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
@ -467,10 +468,115 @@ public class PrePostMethodSecurityConfigurationTests {
|
|||||||
this.methodSecurityService.jsr250RolesAllowedUser();
|
this.methodSecurityService.jsr250RolesAllowedUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetPreFilterThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetPreFilterConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(5);
|
||||||
|
assertThat(filtered).containsExactly("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetPreAuthorizeThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetPreAuthorizeConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(4);
|
||||||
|
assertThat(filtered).containsExactly("DropOnPreAuthorize", "DropOnPostAuthorize", "DropOnPostFilter",
|
||||||
|
"DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetSecuredThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetSecuredConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(3);
|
||||||
|
assertThat(filtered).containsExactly("DropOnPostAuthorize", "DropOnPostFilter", "DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetJsr250WithInsufficientRolesThenFails() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetJsr250Config.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
assertThatExceptionOfType(AccessDeniedException.class)
|
||||||
|
.isThrownBy(() -> this.methodSecurityService.allAnnotations(new ArrayList<>(list)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(roles = "SECURED")
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetJsr250ThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetJsr250Config.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(3);
|
||||||
|
assertThat(filtered).containsExactly("DropOnPostAuthorize", "DropOnPostFilter", "DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(roles = { "SECURED" })
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetPostAuthorizeWithInsufficientRolesThenFails() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetPostAuthorizeConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
assertThatExceptionOfType(AccessDeniedException.class)
|
||||||
|
.isThrownBy(() -> this.methodSecurityService.allAnnotations(new ArrayList<>(list)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(roles = { "SECURED", "JSR250" })
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetPostAuthorizeThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetPostAuthorizeConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(3);
|
||||||
|
assertThat(filtered).containsExactly("DropOnPostAuthorize", "DropOnPostFilter", "DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(roles = { "SECURED", "JSR250" })
|
||||||
|
public void allAnnotationsWhenAdviceBeforeOffsetPostFilterThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnBeforeOffsetPostFilterConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(2);
|
||||||
|
assertThat(filtered).containsExactly("DropOnPostFilter", "DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(roles = { "SECURED", "JSR250" })
|
||||||
|
public void allAnnotationsWhenAdviceAfterAllOffsetThenReturnsFilteredList() {
|
||||||
|
this.spring.register(ReturnAfterAllOffsetConfig.class).autowire();
|
||||||
|
List<String> list = Arrays.asList("DropOnPreFilter", "DropOnPreAuthorize", "DropOnPostAuthorize",
|
||||||
|
"DropOnPostFilter", "DoNotDrop");
|
||||||
|
List<String> filtered = this.methodSecurityService.allAnnotations(new ArrayList<>(list));
|
||||||
|
assertThat(filtered).hasSize(1);
|
||||||
|
assertThat(filtered).containsExactly("DoNotDrop");
|
||||||
|
}
|
||||||
|
|
||||||
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
|
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
|
||||||
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
|
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Advisor returnAdvisor(int order) {
|
||||||
|
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
|
||||||
|
pointcut.setPattern(".*MethodSecurityServiceImpl.*");
|
||||||
|
MethodInterceptor interceptor = (mi) -> mi.getArguments()[0];
|
||||||
|
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, interceptor);
|
||||||
|
advisor.setOrder(order);
|
||||||
|
return advisor;
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableCustomMethodSecurity
|
@EnableCustomMethodSecurity
|
||||||
static class CustomMethodSecurityServiceConfig {
|
static class CustomMethodSecurityServiceConfig {
|
||||||
@ -660,4 +766,105 @@ public class PrePostMethodSecurityConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnBeforeOffsetPreFilterConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnBeforePreFilter() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.PRE_FILTER.getOrder() + OffsetConfig.OFFSET - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnBeforeOffsetPreAuthorizeConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnBeforePreAuthorize() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.PRE_AUTHORIZE.getOrder() + OffsetConfig.OFFSET - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnBeforeOffsetSecuredConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnBeforeSecured() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.SECURED.getOrder() + OffsetConfig.OFFSET - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnBeforeOffsetJsr250Config {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnBeforeJsr250() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.JSR250.getOrder() + OffsetConfig.OFFSET - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnBeforeOffsetPostAuthorizeConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnBeforePreAuthorize() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.POST_AUTHORIZE.getOrder() + OffsetConfig.OFFSET - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnBeforeOffsetPostFilterConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnBeforePostFilter() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.POST_FILTER.getOrder() + OffsetConfig.OFFSET - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(OffsetConfig.class)
|
||||||
|
static class ReturnAfterAllOffsetConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
|
Advisor returnAfterAll() {
|
||||||
|
return returnAdvisor(AuthorizationInterceptorsOrder.POST_FILTER.getOrder() + OffsetConfig.OFFSET + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableMethodSecurity(offset = OffsetConfig.OFFSET, jsr250Enabled = true, securedEnabled = true)
|
||||||
|
static class OffsetConfig {
|
||||||
|
|
||||||
|
static final int OFFSET = 2;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
MethodSecurityService methodSecurityService() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
Authz authz() {
|
||||||
|
return new Authz();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user