Make single definition of defaultRolePrefix and rolePrefix
Previous to this commit, role prefix had to be set in every class causing repetition. Now, bean `GrantedAuthorityDefaults` can be used to define the role prefix in a single point. Fixes gh-3701
This commit is contained in:
+8
-7
@@ -15,11 +15,15 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.authentication.configurers.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.authentication.ProviderManagerBuilder;
|
||||
@@ -43,9 +47,6 @@ import org.springframework.security.ldap.userdetails.PersonContextMapper;
|
||||
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
/**
|
||||
* Configures LDAP {@link AuthenticationProvider} in the {@link ProviderManagerBuilder}.
|
||||
*
|
||||
@@ -60,7 +61,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
private String groupRoleAttribute = "cn";
|
||||
private String groupSearchBase = "";
|
||||
private String groupSearchFilter = "(uniqueMember={0})";
|
||||
private String rolePrefix = "ROLE_";
|
||||
private GrantedAuthorityDefaults rolePrefix = new GrantedAuthorityDefaults("ROLE_");
|
||||
private String userSearchBase = ""; // only for search
|
||||
private String userSearchFilter = null;// "uid={0}"; // only for search
|
||||
private String[] userDnPatterns;
|
||||
@@ -128,7 +129,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
contextSource, groupSearchBase);
|
||||
defaultAuthoritiesPopulator.setGroupRoleAttribute(groupRoleAttribute);
|
||||
defaultAuthoritiesPopulator.setGroupSearchFilter(groupSearchFilter);
|
||||
defaultAuthoritiesPopulator.setRolePrefix(rolePrefix);
|
||||
defaultAuthoritiesPopulator.setRolePrefix(this.rolePrefix.getRolePrefix());
|
||||
|
||||
this.ldapAuthoritiesPopulator = defaultAuthoritiesPopulator;
|
||||
return defaultAuthoritiesPopulator;
|
||||
@@ -161,7 +162,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
}
|
||||
|
||||
SimpleAuthorityMapper simpleAuthorityMapper = new SimpleAuthorityMapper();
|
||||
simpleAuthorityMapper.setPrefix(rolePrefix);
|
||||
simpleAuthorityMapper.setPrefix(this.rolePrefix.getRolePrefix());
|
||||
simpleAuthorityMapper.afterPropertiesSet();
|
||||
this.authoritiesMapper = simpleAuthorityMapper;
|
||||
return simpleAuthorityMapper;
|
||||
@@ -356,7 +357,7 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
|
||||
* @see SimpleAuthorityMapper#setPrefix(String)
|
||||
*/
|
||||
public LdapAuthenticationProviderConfigurer<B> rolePrefix(String rolePrefix) {
|
||||
this.rolePrefix = rolePrefix;
|
||||
this.rolePrefix = new GrantedAuthorityDefaults(rolePrefix);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+26
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -49,6 +49,7 @@ import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.access.intercept.AfterInvocationManager;
|
||||
import org.springframework.security.access.intercept.AfterInvocationProviderManager;
|
||||
import org.springframework.security.access.intercept.RunAsManager;
|
||||
import org.springframework.security.access.intercept.RunAsManagerImpl;
|
||||
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor;
|
||||
import org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource;
|
||||
@@ -63,6 +64,8 @@ import org.springframework.security.access.vote.RoleVoter;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
|
||||
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||
@@ -74,6 +77,7 @@ import org.springframework.util.Assert;
|
||||
* {@link EnableGlobalMethodSecurity} annotation on the subclass.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.2
|
||||
* @see EnableGlobalMethodSecurity
|
||||
*/
|
||||
@@ -130,6 +134,14 @@ public class GlobalMethodSecurityConfiguration
|
||||
.setSecurityMetadataSource(methodSecurityMetadataSource());
|
||||
RunAsManager runAsManager = runAsManager();
|
||||
if (runAsManager != null) {
|
||||
if (runAsManager instanceof RunAsManagerImpl) {
|
||||
GrantedAuthorityDefaults grantedAuthorityDefaults =
|
||||
getSingleBeanOrNull(GrantedAuthorityDefaults.class);
|
||||
if (grantedAuthorityDefaults != null) {
|
||||
((RunAsManagerImpl) runAsManager).setRolePrefix(
|
||||
grantedAuthorityDefaults.getRolePrefix());
|
||||
}
|
||||
}
|
||||
methodSecurityInterceptor.setRunAsManager(runAsManager);
|
||||
}
|
||||
|
||||
@@ -168,6 +180,13 @@ public class GlobalMethodSecurityConfiguration
|
||||
if (trustResolver != null) {
|
||||
this.defaultMethodExpressionHandler.setTrustResolver(trustResolver);
|
||||
}
|
||||
|
||||
GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(
|
||||
GrantedAuthorityDefaults.class);
|
||||
if (grantedAuthorityDefaults != null) {
|
||||
this.defaultMethodExpressionHandler.setDefaultRolePrefix(
|
||||
grantedAuthorityDefaults.getRolePrefix());
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getSingleBeanOrNull(Class<T> type) {
|
||||
@@ -355,6 +374,12 @@ public class GlobalMethodSecurityConfiguration
|
||||
sources.add(new SecuredAnnotationSecurityMetadataSource());
|
||||
}
|
||||
if (jsr250Enabled()) {
|
||||
GrantedAuthorityDefaults grantedAuthorityDefaults =
|
||||
getSingleBeanOrNull(GrantedAuthorityDefaults.class);
|
||||
if (grantedAuthorityDefaults != null) {
|
||||
this.jsr250MethodSecurityMetadataSource.setDefaultRolePrefix(
|
||||
grantedAuthorityDefaults.getRolePrefix());
|
||||
}
|
||||
sources.add(jsr250MethodSecurityMetadataSource);
|
||||
}
|
||||
return new DelegatingMethodSecurityMetadataSource(sources);
|
||||
|
||||
+25
-1
@@ -17,7 +17,8 @@ package org.springframework.security.config.annotation.method.configuration
|
||||
|
||||
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
@@ -496,4 +497,27 @@ public class GlobalMethodSecurityConfigurationTests extends BaseSpringSpec {
|
||||
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:")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
-1
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.springframework.security.config.annotation.method.configuration
|
||||
|
||||
import org.springframework.security.access.annotation.Jsr250MethodSecurityMetadataSource
|
||||
import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat
|
||||
import static org.junit.Assert.fail
|
||||
@@ -146,6 +148,39 @@ public class NamespaceGlobalMethodSecurityTests extends BaseSpringSpec {
|
||||
public static class Jsr250Config extends BaseMethodConfig {
|
||||
}
|
||||
|
||||
def "enable jsr250 with custom role prefix"() {
|
||||
when:
|
||||
context = new AnnotationConfigApplicationContext(Jsr250WithCustomRolePrefixConfig)
|
||||
MethodSecurityService service = context.getBean(MethodSecurityService)
|
||||
then: "@Secured and @PreAuthorize are ignored"
|
||||
service.secured() == null
|
||||
service.preAuthorize() == null
|
||||
|
||||
when: "@DenyAll method invoked"
|
||||
service.jsr250()
|
||||
then: "access is denied"
|
||||
thrown(AccessDeniedException)
|
||||
when: "@PermitAll method invoked"
|
||||
String jsr250PermitAll = service.jsr250PermitAll()
|
||||
then: "access is allowed"
|
||||
jsr250PermitAll == null
|
||||
when:
|
||||
Jsr250MethodSecurityMetadataSource jsr250MethodSecurity = context.getBean(Jsr250MethodSecurityMetadataSource)
|
||||
then:
|
||||
jsr250MethodSecurity.defaultRolePrefix == "ROLE:"
|
||||
}
|
||||
|
||||
@EnableGlobalMethodSecurity(jsr250Enabled = true)
|
||||
@Configuration
|
||||
public static class Jsr250WithCustomRolePrefixConfig extends BaseMethodConfig {
|
||||
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults ga() {
|
||||
return new GrantedAuthorityDefaults("ROLE:")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// --- metadata-source-ref ---
|
||||
|
||||
def "custom MethodSecurityMetadataSource can be used with higher priority than other sources"() {
|
||||
@@ -320,7 +355,7 @@ public class NamespaceGlobalMethodSecurityTests extends BaseSpringSpec {
|
||||
context = new AnnotationConfigApplicationContext(BaseMethodConfig,CustomRunAsManagerConfig)
|
||||
MethodSecurityService service = context.getBean(MethodSecurityService)
|
||||
then:
|
||||
service.runAs().authorities.find { it.authority == "ROLE_RUN_AS_SUPER"}
|
||||
service.runAs().authorities.find { it.authority == "ROLE:RUN_AS_SUPER"}
|
||||
}
|
||||
|
||||
@EnableGlobalMethodSecurity(securedEnabled = true)
|
||||
@@ -331,6 +366,11 @@ public class NamespaceGlobalMethodSecurityTests extends BaseSpringSpec {
|
||||
runAsManager.setKey("some key")
|
||||
return runAsManager
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults ga() {
|
||||
return new GrantedAuthorityDefaults("ROLE:")
|
||||
}
|
||||
}
|
||||
|
||||
// --- secured-annotation ---
|
||||
|
||||
Reference in New Issue
Block a user