SEC-2305: GlobalMethodSecurityConfiguration autowire PermissionEvaluator

If a single PermissionEvaluator bean is found the
DefaultMethodSecurityExpressionHandler is configured with the
PermissionEvaluator. If multiple PermissionEvaluator beans are found, the
beans are ignored.
This commit is contained in:
Rob Winch 2013-09-27 15:46:45 -05:00
parent e696890e8e
commit 614c94187e
2 changed files with 87 additions and 1 deletions

View File

@ -39,6 +39,7 @@ import org.springframework.core.type.AnnotationMetadata;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AfterInvocationProvider;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.annotation.Jsr250MethodSecurityMetadataSource;
import org.springframework.security.access.annotation.Jsr250Voter;
import org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource;
@ -361,6 +362,14 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
this.defaultMethodExpressionHandler = objectPostProcessor.postProcess(defaultMethodExpressionHandler);
}
@Autowired(required = false)
public void setPermissionEvaluator(List<PermissionEvaluator> permissionEvaluators) {
if(permissionEvaluators.size() != 1) {
logger.debug("Not autwiring PermissionEvaluator since size != 1. Got " + permissionEvaluators);
}
this.defaultMethodExpressionHandler.setPermissionEvaluator(permissionEvaluators.get(0));
}
@SuppressWarnings("unchecked")
private <T> T lazyBean(Class<T> interfaceName) {
LazyInitTargetSource lazyTargetSource = new LazyInitTargetSource();

View File

@ -24,6 +24,7 @@ import org.springframework.context.ApplicationListener
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.access.AccessDeniedException
import org.springframework.security.access.PermissionEvaluator
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
import org.springframework.security.authentication.AuthenticationManager
@ -32,7 +33,6 @@ import org.springframework.security.authentication.DefaultAuthenticationEventPub
import org.springframework.security.authentication.TestingAuthenticationToken
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.authentication.event.AuthenticationSuccessEvent
import org.springframework.security.config.MockAfterInvocationProvider;
import org.springframework.security.config.annotation.BaseSpringSpec
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.core.Authentication
@ -199,4 +199,81 @@ public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec {
new MethodSecurityServiceImpl()
}
}
def "GlobalMethodSecurityConfiguration autowires PermissionEvaluator"() {
setup:
SecurityContextHolder.getContext().setAuthentication(
new TestingAuthenticationToken("user", "password","ROLE_USER"))
PermissionEvaluator evaluator = Mock()
AutowirePermissionEvaluatorConfig.PE = evaluator
loadConfig(AutowirePermissionEvaluatorConfig)
MethodSecurityService service = context.getBean(MethodSecurityService)
when:
service.hasPermission("something")
then:
1 * evaluator.hasPermission(_, "something", "read") >> true
when:
service.hasPermission("something")
then:
1 * evaluator.hasPermission(_, "something", "read") >> false
thrown(AccessDeniedException)
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class AutowirePermissionEvaluatorConfig extends GlobalMethodSecurityConfiguration {
static PermissionEvaluator PE
@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth)
throws Exception {
auth
.inMemoryAuthentication()
}
@Bean
public PermissionEvaluator pe() {
PE
}
@Bean
public MethodSecurityService service() {
new MethodSecurityServiceImpl()
}
}
def "GlobalMethodSecurityConfiguration does not failw with multiple PermissionEvaluator"() {
when:
loadConfig(MultiPermissionEvaluatorConfig)
then:
noExceptionThrown()
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class MultiPermissionEvaluatorConfig extends GlobalMethodSecurityConfiguration {
static PermissionEvaluator PE
@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth)
throws Exception {
auth
.inMemoryAuthentication()
}
@Bean
public PermissionEvaluator pe() {
PE
}
@Bean
public PermissionEvaluator pe2() {
PE
}
@Bean
public MethodSecurityService service() {
new MethodSecurityServiceImpl()
}
}
}