Add order offset to @EnableMethodSecurity
Closes gh-13214
This commit is contained in:
committed by
Josh Cummings
parent
c19f3d9d06
commit
99218db84a
@@ -96,6 +96,14 @@ public interface MethodSecurityService {
|
||||
@PostAuthorize("returnObject.size == 2")
|
||||
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
|
||||
@RequireAdminRole
|
||||
void repeatedAnnotations();
|
||||
|
||||
@@ -117,6 +117,11 @@ public class MethodSecurityServiceImpl implements MethodSecurityService {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> allAnnotations(List<String> list) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
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.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Role;
|
||||
import org.springframework.core.annotation.AnnotationConfigurationException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
@@ -467,10 +468,115 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||
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() {
|
||||
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
|
||||
@EnableCustomMethodSecurity
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user