mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-03-05 12:59:22 +00:00
GlobalMethodSecurityConfigurationTests groovy->java
Issue: gh-4939
This commit is contained in:
parent
6c52eb6ee1
commit
6af1ac08db
@ -1,518 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2013 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.springframework.security.config.annotation.method.configuration
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
|
||||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl
|
|
||||||
|
|
||||||
import java.lang.reflect.Proxy
|
|
||||||
|
|
||||||
import org.springframework.beans.BeansException
|
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor
|
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.GlobalAuthenticationConfigurerAdapter
|
|
||||||
import org.springframework.security.config.annotation.method.configuration.NamespaceGlobalMethodSecurityTests.BaseMethodConfig
|
|
||||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
|
||||||
|
|
||||||
import javax.sql.DataSource
|
|
||||||
|
|
||||||
import org.aopalliance.intercept.MethodInterceptor
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
|
||||||
import org.springframework.context.ApplicationContext
|
|
||||||
import org.springframework.context.ApplicationListener
|
|
||||||
import org.springframework.context.annotation.AdviceMode
|
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
|
||||||
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
|
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver
|
|
||||||
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher
|
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
|
||||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent
|
|
||||||
import org.springframework.security.config.annotation.BaseSpringSpec
|
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
|
||||||
import org.springframework.security.config.method.TestPermissionEvaluator;
|
|
||||||
import org.springframework.security.core.Authentication
|
|
||||||
import org.springframework.security.core.authority.AuthorityUtils
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Rob Winch
|
|
||||||
*/
|
|
||||||
public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec {
|
|
||||||
def "messages set when using GlobalMethodSecurityConfiguration"() {
|
|
||||||
when:
|
|
||||||
loadConfig(InMemoryAuthWithGlobalMethodSecurityConfig)
|
|
||||||
then:
|
|
||||||
authenticationManager.messages.messageSource instanceof ApplicationContext
|
|
||||||
}
|
|
||||||
|
|
||||||
def "AuthenticationEventPublisher is registered GlobalMethodSecurityConfiguration"() {
|
|
||||||
when:
|
|
||||||
loadConfig(InMemoryAuthWithGlobalMethodSecurityConfig)
|
|
||||||
then:
|
|
||||||
authenticationManager.eventPublisher instanceof DefaultAuthenticationEventPublisher
|
|
||||||
when:
|
|
||||||
Authentication auth = new UsernamePasswordAuthenticationToken("user",null,AuthorityUtils.createAuthorityList("ROLE_USER"))
|
|
||||||
authenticationManager.eventPublisher.publishAuthenticationSuccess(auth)
|
|
||||||
then:
|
|
||||||
InMemoryAuthWithGlobalMethodSecurityConfig.EVENT.authentication == auth
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
public static class InMemoryAuthWithGlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration implements ApplicationListener<AuthenticationSuccessEvent> {
|
|
||||||
static AuthenticationSuccessEvent EVENT
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth
|
|
||||||
.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onApplicationEvent(AuthenticationSuccessEvent e) {
|
|
||||||
EVENT = e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AuthenticationManager getAuthenticationManager() {
|
|
||||||
context.getBean(MethodInterceptor).authenticationManager
|
|
||||||
}
|
|
||||||
|
|
||||||
def "AuthenticationTrustResolver autowires"() {
|
|
||||||
setup:
|
|
||||||
CustomTrustResolverConfig.TR = Mock(AuthenticationTrustResolver)
|
|
||||||
when:
|
|
||||||
loadConfig(CustomTrustResolverConfig)
|
|
||||||
def preAdviceVoter = context.getBean(MethodInterceptor).accessDecisionManager.decisionVoters.find { it instanceof PreInvocationAuthorizationAdviceVoter}
|
|
||||||
then:
|
|
||||||
preAdviceVoter.preAdvice.expressionHandler.trustResolver == CustomTrustResolverConfig.TR
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
static class CustomTrustResolverConfig extends GlobalMethodSecurityConfiguration {
|
|
||||||
static AuthenticationTrustResolver TR
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth
|
|
||||||
.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthenticationTrustResolver 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
|
|
||||||
static class ExpressionHandlerHasBeanResolverSetConfig extends GlobalMethodSecurityConfiguration {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "Method Security supports annotations on interface parameter names"() {
|
|
||||||
setup:
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(
|
|
||||||
new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
|
||||||
loadConfig(MethodSecurityServiceConfig)
|
|
||||||
MethodSecurityService service = context.getBean(MethodSecurityService)
|
|
||||||
when: "service with annotated argument"
|
|
||||||
service.postAnnotation('deny')
|
|
||||||
then: "properly throws AccessDeniedException"
|
|
||||||
thrown(AccessDeniedException)
|
|
||||||
when: "service with annotated argument"
|
|
||||||
service.postAnnotation('grant')
|
|
||||||
then: "properly throws AccessDeniedException"
|
|
||||||
noExceptionThrown()
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
static class MethodSecurityServiceConfig extends GlobalMethodSecurityConfiguration {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth
|
|
||||||
.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityService service() {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
public static class AutowirePermissionEvaluatorConfig extends GlobalMethodSecurityConfiguration {
|
|
||||||
static PermissionEvaluator PE
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(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()
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
public static class MultiPermissionEvaluatorConfig extends GlobalMethodSecurityConfiguration {
|
|
||||||
static PermissionEvaluator PE = new TestPermissionEvaluator()
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth
|
|
||||||
.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PermissionEvaluator pe() {
|
|
||||||
PE
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PermissionEvaluator pe2() {
|
|
||||||
PE
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityService service() {
|
|
||||||
new MethodSecurityServiceImpl()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "SEC-2425: EnableGlobalMethodSecurity works on superclass"() {
|
|
||||||
setup:
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(
|
|
||||||
new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
|
||||||
loadConfig(ParentConfig)
|
|
||||||
MethodSecurityService service = context.getBean(MethodSecurityService)
|
|
||||||
when:
|
|
||||||
service.preAuthorize()
|
|
||||||
then:
|
|
||||||
thrown(AccessDeniedException)
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ChildConfig extends ParentConfig {}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
static class ParentConfig {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected void configurGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth
|
|
||||||
.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityService service() {
|
|
||||||
new MethodSecurityServiceImpl()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "SEC-2479: Support AuthenticationManager in parent"() {
|
|
||||||
setup:
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(
|
|
||||||
new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
|
||||||
loadConfig(Sec2479ParentConfig)
|
|
||||||
def child = new AnnotationConfigApplicationContext()
|
|
||||||
child.register(Sec2479ChildConfig)
|
|
||||||
child.parent = context
|
|
||||||
child.refresh()
|
|
||||||
MethodSecurityService service = child.getBean(MethodSecurityService)
|
|
||||||
when:
|
|
||||||
service.preAuthorize()
|
|
||||||
then:
|
|
||||||
thrown(AccessDeniedException)
|
|
||||||
cleanup:
|
|
||||||
child?.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
static class Sec2479ParentConfig {
|
|
||||||
static AuthenticationManager AM
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthenticationManager am() {
|
|
||||||
AM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
static class Sec2479ChildConfig {
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityService service() {
|
|
||||||
new MethodSecurityServiceImpl()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "SEC-2815: @EnableGlobalMethodSecurity does not trigger eager initialization of Beans in GlobalAuthenticationConfigurer"() {
|
|
||||||
setup:
|
|
||||||
Sec2815Config.dataSource = Mock(DataSource)
|
|
||||||
when: 'load a Configuration that uses a Bean (DataSource) in a GlobalAuthenticationConfigurerAdapter'
|
|
||||||
loadConfig(Sec2815Config)
|
|
||||||
then: 'The Bean (DataSource) is still properly post processed with all BeanPostProcessor'
|
|
||||||
context.getBean(MockBeanPostProcessor).beforeInit['dataSource']
|
|
||||||
context.getBean(MockBeanPostProcessor).afterInit['dataSource']
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
static class Sec2815Config {
|
|
||||||
static DataSource dataSource;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityService service() {
|
|
||||||
new MethodSecurityServiceImpl()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MockBeanPostProcessor mockBeanPostProcessor() {
|
|
||||||
new MockBeanPostProcessor()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public DataSource dataSource() {
|
|
||||||
dataSource
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
static class AuthConfig extends GlobalAuthenticationConfigurerAdapter {
|
|
||||||
@Autowired
|
|
||||||
DataSource dataSource
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void init(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static class MockBeanPostProcessor implements BeanPostProcessor {
|
|
||||||
Map<String,Object> beforeInit = new HashMap<String,Object>()
|
|
||||||
Map<String,Object> afterInit = new HashMap<String,Object>()
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
|
||||||
beforeInit[beanName] = bean
|
|
||||||
bean
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
|
||||||
afterInit[beanName] = bean
|
|
||||||
bean
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "SEC-3045: Global Security proxies security"() {
|
|
||||||
setup:
|
|
||||||
when: 'load a Configuration that uses a Bean (DataSource) in a GlobalAuthenticationConfigurerAdapter'
|
|
||||||
loadConfig(Sec3005Config)
|
|
||||||
MethodSecurityService service = context.getBean(MethodSecurityService)
|
|
||||||
then: 'The Bean (DataSource) is still properly post processed with all BeanPostProcessor'
|
|
||||||
!Proxy.isProxyClass(service.getClass())
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, mode= AdviceMode.ASPECTJ)
|
|
||||||
@EnableTransactionManagement
|
|
||||||
static class Sec3005Config {
|
|
||||||
static DataSource dataSource;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityService service() {
|
|
||||||
new MethodSecurityServiceImpl()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) {
|
|
||||||
auth.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// gh-3797
|
|
||||||
def preAuthorizeBeanSpel() {
|
|
||||||
setup:
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(
|
|
||||||
new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
|
||||||
context = new AnnotationConfigApplicationContext(PreAuthorizeBeanSpelConfig)
|
|
||||||
BeanSpelService service = context.getBean(BeanSpelService)
|
|
||||||
when:
|
|
||||||
service.run(true)
|
|
||||||
then:
|
|
||||||
noExceptionThrown()
|
|
||||||
when:
|
|
||||||
service.run(false)
|
|
||||||
then:
|
|
||||||
thrown(AccessDeniedException)
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
@Configuration
|
|
||||||
public static class PreAuthorizeBeanSpelConfig extends BaseMethodConfig {
|
|
||||||
@Bean
|
|
||||||
BeanSpelService service() {
|
|
||||||
return new BeanSpelService();
|
|
||||||
}
|
|
||||||
@Bean
|
|
||||||
BeanSpelSecurity security() {
|
|
||||||
return new BeanSpelSecurity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class BeanSpelService {
|
|
||||||
@PreAuthorize("@security.check(#arg)")
|
|
||||||
void run(boolean arg) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class BeanSpelSecurity {
|
|
||||||
public boolean check(boolean arg) {
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// gh-3394
|
|
||||||
def roleHierarchy() {
|
|
||||||
setup:
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(
|
|
||||||
new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
|
||||||
context = new AnnotationConfigApplicationContext(RoleHierarchyConfig)
|
|
||||||
MethodSecurityService service = context.getBean(MethodSecurityService)
|
|
||||||
when:
|
|
||||||
service.preAuthorizeAdmin()
|
|
||||||
then:
|
|
||||||
noExceptionThrown()
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
@Configuration
|
|
||||||
public static class RoleHierarchyConfig extends BaseMethodConfig {
|
|
||||||
@Bean
|
|
||||||
RoleHierarchy roleHierarchy() {
|
|
||||||
return new RoleHierarchyImpl(hierarchy:"ROLE_USER > ROLE_ADMIN")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "GrantedAuthorityDefaults autowires"() {
|
|
||||||
when:
|
|
||||||
loadConfig(CustomGrantedAuthorityConfig)
|
|
||||||
def preAdviceVoter = context.getBean(MethodInterceptor).accessDecisionManager.decisionVoters.find { it instanceof PreInvocationAuthorizationAdviceVoter}
|
|
||||||
then:
|
|
||||||
preAdviceVoter.preAdvice.expressionHandler.defaultRolePrefix == "ROLE:"
|
|
||||||
}
|
|
||||||
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
||||||
static class CustomGrantedAuthorityConfig extends GlobalMethodSecurityConfiguration {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth
|
|
||||||
.inMemoryAuthentication()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GrantedAuthorityDefaults ga() {
|
|
||||||
return new GrantedAuthorityDefaults("ROLE:")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,484 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.security.config.annotation.method.configuration;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
|
import org.springframework.context.annotation.AdviceMode;
|
||||||
|
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.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
|
||||||
|
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
|
||||||
|
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
|
||||||
|
import org.springframework.security.config.MockEventListener;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.authentication.configuration.GlobalAuthenticationConfigurerAdapter;
|
||||||
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||||
|
import org.springframework.security.config.test.SpringTestRule;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
|
||||||
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Rob Winch
|
||||||
|
*/
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@SecurityTestExecutionListeners
|
||||||
|
public class GlobalMethodSecurityConfigurationTests {
|
||||||
|
@Rule
|
||||||
|
public final SpringTestRule spring = new SpringTestRule();
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
private MethodSecurityService service;
|
||||||
|
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void setMethodInterceptor(MethodSecurityInterceptor interceptor) {
|
||||||
|
this.authenticationManager = interceptor.getAuthenticationManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
MockEventListener<AbstractAuthenticationEvent> events;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void methodSecurityAuthenticationManagerPublishesEvent() {
|
||||||
|
this.spring.register(InMemoryAuthWithGlobalMethodSecurityConfig.class).autowire();
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("foo", "bar"));
|
||||||
|
} catch(AuthenticationException e) {}
|
||||||
|
|
||||||
|
assertThat(this.events.getEvents()).extracting(Object::getClass).containsOnly((Class) AuthenticationFailureBadCredentialsEvent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
public static class InMemoryAuthWithGlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
|
||||||
|
@Override
|
||||||
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth
|
||||||
|
.inMemoryAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MockEventListener<AbstractAuthenticationEvent> listener() {
|
||||||
|
return new MockEventListener<AbstractAuthenticationEvent>() {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void methodSecurityWhenAuthenticationTrustResolverIsBeanThenAutowires() {
|
||||||
|
this.spring.register(CustomTrustResolverConfig.class).autowire();
|
||||||
|
|
||||||
|
AuthenticationTrustResolver trustResolver = this.spring.getContext().getBean(AuthenticationTrustResolver.class);
|
||||||
|
when(trustResolver.isAnonymous(any())).thenReturn(true, false);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorizeNotAnonymous())
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
|
||||||
|
this.service.preAuthorizeNotAnonymous();
|
||||||
|
|
||||||
|
verify(trustResolver, atLeastOnce()).isAnonymous(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
static class CustomTrustResolverConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationTrustResolver trustResolver() {
|
||||||
|
return mock(AuthenticationTrustResolver.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityServiceImpl service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEC-2301
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void defaultWebSecurityExpressionHandlerHasBeanResolverSet() {
|
||||||
|
this.spring.register(ExpressionHandlerHasBeanResolverSetConfig.class).autowire();
|
||||||
|
Authz authz = this.spring.getContext().getBean(Authz.class);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorizeBean(false))
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
|
||||||
|
this.service.preAuthorizeBean(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
|
||||||
|
static class ExpressionHandlerHasBeanResolverSetConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityServiceImpl service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Authz authz() {
|
||||||
|
return new Authz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void methodSecuritySupportsAnnotaitonsOnInterfaceParamerNames() {
|
||||||
|
this.spring.register(MethodSecurityServiceConfig.class).autowire();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.postAnnotation("deny"))
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
|
||||||
|
this.service.postAnnotation("grant");
|
||||||
|
// no exception
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
static class MethodSecurityServiceConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void globalMethodSecurityConfigurationAutowiresPermissionEvaluator() {
|
||||||
|
this.spring.register(AutowirePermissionEvaluatorConfig.class).autowire();
|
||||||
|
PermissionEvaluator permission = this.spring.getContext().getBean(PermissionEvaluator.class);
|
||||||
|
when(permission.hasPermission(any(), eq("something"), eq("read"))).thenReturn(true, false);
|
||||||
|
|
||||||
|
this.service.hasPermission("something");
|
||||||
|
// no exception
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.hasPermission("something"))
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
public static class AutowirePermissionEvaluatorConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PermissionEvaluator permissionEvaluator() {
|
||||||
|
return mock(PermissionEvaluator.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void multiPermissionEvaluatorConfig() throws Exception {
|
||||||
|
this.spring.register(MultiPermissionEvaluatorConfig.class).autowire();
|
||||||
|
|
||||||
|
// no exception
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
public static class MultiPermissionEvaluatorConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PermissionEvaluator permissionEvaluator() {
|
||||||
|
return mock(PermissionEvaluator.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PermissionEvaluator permissionEvaluator2() {
|
||||||
|
return mock(PermissionEvaluator.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEC-2425
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void enableGlobalMethodSecurityWorksOnSuperclass() {
|
||||||
|
this.spring.register(ChildConfig.class).autowire();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorize())
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class ChildConfig extends ParentConfig {}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
static class ParentConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEC-2479
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void supportAuthenticationManagerInParent() {
|
||||||
|
try (AnnotationConfigWebApplicationContext parent = new AnnotationConfigWebApplicationContext()) {
|
||||||
|
parent.register(Sec2479ParentConfig.class);
|
||||||
|
parent.refresh();
|
||||||
|
try (AnnotationConfigWebApplicationContext child = new AnnotationConfigWebApplicationContext()) {
|
||||||
|
child.setParent(parent);
|
||||||
|
child.register(Sec2479ChildConfig.class);
|
||||||
|
child.refresh();
|
||||||
|
this.spring.context(child).autowire();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorize())
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class Sec2479ParentConfig {
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager am() {
|
||||||
|
return mock(AuthenticationManager.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
static class Sec2479ChildConfig {
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void enableGlobalMethodSecurityDoesNotTriggerEagerInitializationOfBeansInGlobalAuthenticationConfigurer() {
|
||||||
|
this.spring.register(Sec2815Config.class).autowire();
|
||||||
|
|
||||||
|
MockBeanPostProcessor pp = this.spring.getContext().getBean(MockBeanPostProcessor.class);
|
||||||
|
|
||||||
|
assertThat(pp.beforeInit).containsKeys("dataSource");
|
||||||
|
assertThat(pp.afterInit).containsKeys("dataSource");
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
static class Sec2815Config {
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MockBeanPostProcessor mockBeanPostProcessor() {
|
||||||
|
return new MockBeanPostProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
return mock(DataSource.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
static class AuthConfig extends GlobalAuthenticationConfigurerAdapter {
|
||||||
|
@Autowired
|
||||||
|
DataSource dataSource;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth.inMemoryAuthentication();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MockBeanPostProcessor implements BeanPostProcessor {
|
||||||
|
Map<String,Object> beforeInit = new HashMap<String,Object>();
|
||||||
|
Map<String,Object> afterInit = new HashMap<String,Object>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object postProcessBeforeInitialization(Object bean, String beanName) throws
|
||||||
|
BeansException {
|
||||||
|
this.beforeInit.put(beanName, bean);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||||
|
this.afterInit.put(beanName, bean);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEC-3045
|
||||||
|
@Test
|
||||||
|
public void globalSecurityProxiesSecurity() {
|
||||||
|
this.spring.register(Sec3005Config.class).autowire();
|
||||||
|
|
||||||
|
assertThat(this.service.getClass()).matches(c-> !Proxy.isProxyClass(c), "is not proxy class");
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true, mode= AdviceMode.ASPECTJ)
|
||||||
|
@EnableTransactionManagement
|
||||||
|
static class Sec3005Config {
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth.inMemoryAuthentication();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// // gh-3797
|
||||||
|
// def preAuthorizeBeanSpel() {
|
||||||
|
// setup:
|
||||||
|
// SecurityContextHolder.getContext().setAuthentication(
|
||||||
|
// new TestingAuthenticationToken("user", "password","ROLE_USER"))
|
||||||
|
// context = new AnnotationConfigApplicationContext(PreAuthorizeBeanSpelConfig)
|
||||||
|
// BeanSpelService service = context.getBean(BeanSpelService)
|
||||||
|
// when:
|
||||||
|
// service.run(true)
|
||||||
|
// then:
|
||||||
|
// noExceptionThrown()
|
||||||
|
// when:
|
||||||
|
// service.run(false)
|
||||||
|
// then:
|
||||||
|
// thrown(AccessDeniedException)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void preAuthorizeBeanSpel() {
|
||||||
|
this.spring.register(PreAuthorizeBeanSpelConfig.class).autowire();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorizeBean(false))
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
|
||||||
|
this.service.preAuthorizeBean(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
public static class PreAuthorizeBeanSpelConfig {
|
||||||
|
@Bean
|
||||||
|
MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
Authz authz() {
|
||||||
|
return new Authz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// gh-3394
|
||||||
|
@Test
|
||||||
|
@WithMockUser
|
||||||
|
public void roleHierarchy() {
|
||||||
|
this.spring.register(RoleHierarchyConfig.class).autowire();
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorize())
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
this.service.preAuthorizeAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
@Configuration
|
||||||
|
public static class RoleHierarchyConfig {
|
||||||
|
@Bean
|
||||||
|
MethodSecurityService service() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RoleHierarchy roleHierarchy() {
|
||||||
|
RoleHierarchyImpl result = new RoleHierarchyImpl();
|
||||||
|
result.setHierarchy("ROLE_USER > ROLE_ADMIN");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(authorities = "ROLE:USER")
|
||||||
|
public void grantedAuthorityDefaultsAutowires() {
|
||||||
|
this.spring.register(CustomGrantedAuthorityConfig.class).autowire();
|
||||||
|
|
||||||
|
CustomGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext().getBean(
|
||||||
|
CustomGrantedAuthorityConfig.CustomAuthorityService.class);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> this.service.preAuthorize())
|
||||||
|
.isInstanceOf(AccessDeniedException.class);
|
||||||
|
|
||||||
|
customService.customPrefixRoleUser();
|
||||||
|
// no exception
|
||||||
|
}
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
static class CustomGrantedAuthorityConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GrantedAuthorityDefaults ga() {
|
||||||
|
return new GrantedAuthorityDefaults("ROLE:");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CustomAuthorityService service() {
|
||||||
|
return new CustomAuthorityService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MethodSecurityServiceImpl methodSecurityService() {
|
||||||
|
return new MethodSecurityServiceImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CustomAuthorityService {
|
||||||
|
@PreAuthorize("hasRole('ROLE:USER')")
|
||||||
|
public void customPrefixRoleUser() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user