SEC-2301: GlobalMethodSecurityConfiguration sets DefaultWebSecurityExpressionHandler BeanResolver
This commit is contained in:
parent
f294480e6b
commit
a3d112979f
|
@ -64,6 +64,7 @@ import org.springframework.security.access.vote.RoleVoter;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
|
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
|
||||||
|
import org.springframework.security.config.PostProcessedMockUserDetailsService;
|
||||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -206,7 +207,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected MethodSecurityExpressionHandler expressionHandler() {
|
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
||||||
return defaultMethodExpressionHandler;
|
return defaultMethodExpressionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +218,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
|
||||||
*/
|
*/
|
||||||
protected final MethodSecurityExpressionHandler getExpressionHandler() {
|
protected final MethodSecurityExpressionHandler getExpressionHandler() {
|
||||||
if(expressionHandler == null) {
|
if(expressionHandler == null) {
|
||||||
expressionHandler = expressionHandler();
|
expressionHandler = createExpressionHandler();
|
||||||
}
|
}
|
||||||
return expressionHandler;
|
return expressionHandler;
|
||||||
}
|
}
|
||||||
|
@ -358,6 +359,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware {
|
||||||
@Autowired(required=false)
|
@Autowired(required=false)
|
||||||
public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
||||||
this.objectPostProcessor = objectPostProcessor;
|
this.objectPostProcessor = objectPostProcessor;
|
||||||
|
this.defaultMethodExpressionHandler = objectPostProcessor.postProcess(defaultMethodExpressionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -23,18 +23,21 @@ import org.springframework.context.ApplicationContext
|
||||||
import org.springframework.context.ApplicationListener
|
import org.springframework.context.ApplicationListener
|
||||||
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.security.access.AccessDecisionManager
|
import org.springframework.security.access.AccessDeniedException
|
||||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler
|
import org.springframework.security.access.prepost.PreAuthorize
|
||||||
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
|
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
|
||||||
import org.springframework.security.authentication.AuthenticationManager
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver
|
import org.springframework.security.authentication.AuthenticationTrustResolver
|
||||||
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher
|
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher
|
||||||
|
import org.springframework.security.authentication.TestingAuthenticationToken
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent
|
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.BaseSpringSpec
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
||||||
import org.springframework.security.core.Authentication
|
import org.springframework.security.core.Authentication
|
||||||
import org.springframework.security.core.authority.AuthorityUtils
|
import org.springframework.security.core.authority.AuthorityUtils
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -109,4 +112,58 @@ public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec {
|
||||||
return TR
|
return TR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def "SEC-2301: DefaultWebSecurityExpressionHandler has BeanResolver set"() {
|
||||||
|
setup:
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(
|
||||||
|
new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
||||||
|
loadConfig(ExpressionHandlerHasBeanResolverSetConfig)
|
||||||
|
def service = context.getBean(ServiceImpl)
|
||||||
|
when: "service with bean reference on PreAuthorize invoked"
|
||||||
|
service.message()
|
||||||
|
then: "properly throws AccessDeniedException"
|
||||||
|
thrown(AccessDeniedException)
|
||||||
|
when: "service with bean reference on PreAuthorize invoked"
|
||||||
|
context.getBean(CustomAuthzService).grantAccess = true
|
||||||
|
service.message()
|
||||||
|
then: "grants access too"
|
||||||
|
noExceptionThrown()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
|
||||||
|
static class ExpressionHandlerHasBeanResolverSetConfig extends GlobalMethodSecurityConfiguration {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerAuthentication(AuthenticationManagerBuilder auth)
|
||||||
|
throws Exception {
|
||||||
|
auth
|
||||||
|
.inMemoryAuthentication()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ServiceImpl service() {
|
||||||
|
return new ServiceImpl()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CustomAuthzService authz() {
|
||||||
|
return new CustomAuthzService()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ServiceImpl {
|
||||||
|
@PreAuthorize("@authz.authorize()")
|
||||||
|
public String message() {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CustomAuthzService {
|
||||||
|
boolean grantAccess
|
||||||
|
|
||||||
|
public boolean authorize() {
|
||||||
|
grantAccess
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class NamespaceGlobalMethodSecurityExpressionHandlerTests extends BaseSpr
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
public static class CustomAccessDecisionManagerConfig extends GlobalMethodSecurityConfiguration {
|
public static class CustomAccessDecisionManagerConfig extends GlobalMethodSecurityConfiguration {
|
||||||
@Override
|
@Override
|
||||||
protected MethodSecurityExpressionHandler expressionHandler() {
|
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
||||||
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler()
|
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler()
|
||||||
expressionHandler.permissionEvaluator = new PermissionEvaluator() {
|
expressionHandler.permissionEvaluator = new PermissionEvaluator() {
|
||||||
boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
|
boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
|
||||||
|
|
|
@ -97,7 +97,7 @@ public class SampleEnableGlobalMethodSecurityTests extends BaseSpringSpec {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MethodSecurityExpressionHandler expressionHandler() {
|
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
||||||
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||||
expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
|
expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
|
||||||
return expressionHandler;
|
return expressionHandler;
|
||||||
|
|
Loading…
Reference in New Issue