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:
parent
2e6656e9d3
commit
eabeaf35d6
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ---
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Eddú Meléndez
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class GrantedAuthorityDefaults {
|
||||
|
||||
private String rolePrefix = "ROLE_";
|
||||
|
||||
public GrantedAuthorityDefaults(String rolePrefix) {
|
||||
this.rolePrefix = rolePrefix;
|
||||
}
|
||||
|
||||
public String getRolePrefix() {
|
||||
return this.rolePrefix;
|
||||
}
|
||||
|
||||
public void setRolePrefix(String rolePrefix) {
|
||||
this.rolePrefix = rolePrefix;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
package org.springframework.security.ldap.userdetails;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.ldap.SpringSecurityLdapTemplate;
|
||||
|
@ -97,7 +101,7 @@ import java.util.Set;
|
|||
* @author Luke Taylor
|
||||
* @author Filip Hanik
|
||||
*/
|
||||
public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {
|
||||
public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator, ApplicationContextAware {
|
||||
// ~ Static fields/initializers
|
||||
// =====================================================================================
|
||||
|
||||
|
@ -140,7 +144,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
|||
/**
|
||||
* The role prefix that will be prepended to each role name
|
||||
*/
|
||||
private String rolePrefix = "ROLE_";
|
||||
private GrantedAuthorityDefaults rolePrefix = new GrantedAuthorityDefaults("ROLE_");
|
||||
/**
|
||||
* Should we convert the role name to uppercase
|
||||
*/
|
||||
|
@ -250,7 +254,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
|||
role = role.toUpperCase();
|
||||
}
|
||||
|
||||
authorities.add(new SimpleGrantedAuthority(rolePrefix + role));
|
||||
authorities.add(new SimpleGrantedAuthority(rolePrefix.getRolePrefix() + role));
|
||||
}
|
||||
|
||||
return authorities;
|
||||
|
@ -297,7 +301,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
|||
*/
|
||||
public void setRolePrefix(String rolePrefix) {
|
||||
Assert.notNull(rolePrefix, "rolePrefix must not be null");
|
||||
this.rolePrefix = rolePrefix;
|
||||
this.rolePrefix = new GrantedAuthorityDefaults(rolePrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,7 +364,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
|||
* @see #setRolePrefix(String)
|
||||
*/
|
||||
protected final String getRolePrefix() {
|
||||
return rolePrefix;
|
||||
return this.rolePrefix.getRolePrefix();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -391,4 +395,14 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
|||
private SearchControls getSearchControls() {
|
||||
return searchControls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws
|
||||
BeansException {
|
||||
String[] beanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
|
||||
if (beanNames.length == 1) {
|
||||
this.rolePrefix = context.getBean(beanNames[0], GrantedAuthorityDefaults.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,8 +20,13 @@ import java.util.Collection;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
@ -34,14 +39,15 @@ import org.springframework.util.Assert;
|
|||
* object.
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class LdapUserDetailsMapper implements UserDetailsContextMapper {
|
||||
public class LdapUserDetailsMapper implements UserDetailsContextMapper, ApplicationContextAware {
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private final Log logger = LogFactory.getLog(LdapUserDetailsMapper.class);
|
||||
private String passwordAttributeName = "userPassword";
|
||||
private String rolePrefix = "ROLE_";
|
||||
private GrantedAuthorityDefaults rolePrefix = new GrantedAuthorityDefaults("ROLE_");
|
||||
private String[] roleAttributes = null;
|
||||
private boolean convertToUpperCase = true;
|
||||
|
||||
|
@ -146,7 +152,7 @@ public class LdapUserDetailsMapper implements UserDetailsContextMapper {
|
|||
if (convertToUpperCase) {
|
||||
role = ((String) role).toUpperCase();
|
||||
}
|
||||
return new SimpleGrantedAuthority(rolePrefix + role);
|
||||
return new SimpleGrantedAuthority(this.rolePrefix.getRolePrefix() + role);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -188,6 +194,16 @@ public class LdapUserDetailsMapper implements UserDetailsContextMapper {
|
|||
* @param rolePrefix the prefix (defaults to "ROLE_").
|
||||
*/
|
||||
public void setRolePrefix(String rolePrefix) {
|
||||
this.rolePrefix = rolePrefix;
|
||||
this.rolePrefix = new GrantedAuthorityDefaults(rolePrefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws
|
||||
BeansException {
|
||||
String[] beanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
|
||||
if (beanNames.length == 1) {
|
||||
this.rolePrefix = context.getBean(beanNames[0], GrantedAuthorityDefaults.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.
|
||||
* 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.ldap.userdetails;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ldap.core.ContextSource;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class DefaultLdapAuthoritiesPopulatorTests {
|
||||
|
||||
@Test
|
||||
public void testDefaultRolePrefix() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(LdapAuthoritiesPopulatorConfiguration.class);
|
||||
context.refresh();
|
||||
|
||||
DefaultLdapAuthoritiesPopulator ldapPopulator = context.getBean(DefaultLdapAuthoritiesPopulator.class);
|
||||
assertThat(ldapPopulator.getRolePrefix()).isEqualTo("ROL_");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class LdapAuthoritiesPopulatorConfiguration {
|
||||
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults authorityDefaults() {
|
||||
return new GrantedAuthorityDefaults("ROL_");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultLdapAuthoritiesPopulator ldapAuthoritiesPopulator() {
|
||||
ContextSource contextSource = mock(ContextSource.class);
|
||||
return new DefaultLdapAuthoritiesPopulator(contextSource, "ou=groups");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -21,9 +21,14 @@ import javax.naming.directory.BasicAttributes;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DistinguishedName;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -94,4 +99,32 @@ public class LdapUserDetailsMapperTests {
|
|||
|
||||
assertThat(user.getPassword()).isEqualTo("mypassword");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRolePrefix() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(LdapUserDetailsMapperConfiguration.class);
|
||||
context.refresh();
|
||||
|
||||
LdapUserDetailsMapper ldapUserDetailsMapper = context.getBean(LdapUserDetailsMapper.class);
|
||||
|
||||
GrantedAuthorityDefaults rolePrefix = (GrantedAuthorityDefaults) ReflectionTestUtils.getField(ldapUserDetailsMapper, "rolePrefix");
|
||||
assertThat(rolePrefix.getRolePrefix()).isEqualTo("ROL_");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class LdapUserDetailsMapperConfiguration {
|
||||
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults authorityDefaults() {
|
||||
return new GrantedAuthorityDefaults("ROL_");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LdapUserDetailsMapper ldapUserDetailsMapper() {
|
||||
return new LdapUserDetailsMapper();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,11 +15,14 @@
|
|||
*/
|
||||
package org.springframework.security.web.access.expression;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.access.expression.AbstractSecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.SecurityExpressionHandler;
|
||||
import org.springframework.security.access.expression.SecurityExpressionOperations;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
import org.springframework.util.Assert;
|
||||
|
@ -27,6 +30,7 @@ import org.springframework.util.Assert;
|
|||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
* @author Eddú Meléndez
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DefaultWebSecurityExpressionHandler extends
|
||||
|
@ -34,7 +38,7 @@ public class DefaultWebSecurityExpressionHandler extends
|
|||
SecurityExpressionHandler<FilterInvocation> {
|
||||
|
||||
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||
private String defaultRolePrefix = "ROLE_";
|
||||
private GrantedAuthorityDefaults defaultRolePrefix = new GrantedAuthorityDefaults("ROLE_");
|
||||
|
||||
@Override
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(
|
||||
|
@ -43,7 +47,7 @@ public class DefaultWebSecurityExpressionHandler extends
|
|||
root.setPermissionEvaluator(getPermissionEvaluator());
|
||||
root.setTrustResolver(trustResolver);
|
||||
root.setRoleHierarchy(getRoleHierarchy());
|
||||
root.setDefaultRolePrefix(defaultRolePrefix);
|
||||
root.setDefaultRolePrefix(this.defaultRolePrefix.getRolePrefix());
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -74,6 +78,16 @@ public class DefaultWebSecurityExpressionHandler extends
|
|||
* @param defaultRolePrefix the default prefix to add to roles. Default "ROLE_".
|
||||
*/
|
||||
public void setDefaultRolePrefix(String defaultRolePrefix) {
|
||||
this.defaultRolePrefix = defaultRolePrefix;
|
||||
this.defaultRolePrefix = new GrantedAuthorityDefaults(defaultRolePrefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) {
|
||||
super.setApplicationContext(context);
|
||||
String[] beanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
|
||||
if (beanNames.length == 1) {
|
||||
this.defaultRolePrefix = context.getBean(beanNames[0], GrantedAuthorityDefaults.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -27,9 +27,13 @@ import javax.servlet.ServletResponse;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
@ -71,12 +75,13 @@ import org.springframework.web.filter.GenericFilterBean;
|
|||
* @author Ben Alex
|
||||
* @author Luke Taylor
|
||||
* @author Rob Winch
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
||||
public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean implements ApplicationContextAware {
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
|
||||
private String rolePrefix = "ROLE_";
|
||||
private GrantedAuthorityDefaults rolePrefix = new GrantedAuthorityDefaults("ROLE_");
|
||||
|
||||
private HttpServletRequestFactory requestFactory;
|
||||
|
||||
|
@ -93,7 +98,7 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||
|
||||
public void setRolePrefix(String rolePrefix) {
|
||||
Assert.notNull(rolePrefix, "Role prefix must not be null");
|
||||
this.rolePrefix = rolePrefix;
|
||||
this.rolePrefix = new GrantedAuthorityDefaults(rolePrefix);
|
||||
updateFactory();
|
||||
}
|
||||
|
||||
|
@ -177,8 +182,9 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||
}
|
||||
|
||||
private void updateFactory() {
|
||||
this.requestFactory = isServlet3() ? createServlet3Factory(this.rolePrefix)
|
||||
: new HttpServlet25RequestFactory(this.trustResolver, this.rolePrefix);
|
||||
String rolePrefix = this.rolePrefix.getRolePrefix();
|
||||
this.requestFactory = isServlet3() ? createServlet3Factory(rolePrefix)
|
||||
: new HttpServlet25RequestFactory(this.trustResolver, rolePrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,4 +216,14 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||
private boolean isServlet3() {
|
||||
return ClassUtils.hasMethod(ServletRequest.class, "startAsync");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws
|
||||
BeansException {
|
||||
String[] beanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
|
||||
if (beanNames.length == 1) {
|
||||
this.rolePrefix = context.getBean(beanNames[0], GrantedAuthorityDefaults.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.springframework.expression.Expression;
|
|||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.security.access.SecurityConfig;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.FilterInvocation;
|
||||
|
@ -62,7 +63,7 @@ public class DefaultWebSecurityExpressionHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void expressionPropertiesAreResolvedAgainsAppContextBeans() throws Exception {
|
||||
public void expressionPropertiesAreResolvedAgainstAppContextBeans() throws Exception {
|
||||
StaticApplicationContext appContext = new StaticApplicationContext();
|
||||
RootBeanDefinition bean = new RootBeanDefinition(SecurityConfig.class);
|
||||
bean.getConstructorArgumentValues().addGenericArgumentValue("ROLE_A");
|
||||
|
@ -95,4 +96,22 @@ public class DefaultWebSecurityExpressionHandlerTests {
|
|||
|
||||
verify(trustResolver).isAnonymous(authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRolePrefix() {
|
||||
StaticApplicationContext appContext = new StaticApplicationContext();
|
||||
RootBeanDefinition bean = new RootBeanDefinition(GrantedAuthorityDefaults.class);
|
||||
bean.getConstructorArgumentValues().addGenericArgumentValue("ROL_");
|
||||
appContext.registerBeanDefinition("authorityDefaults", bean);
|
||||
handler.setApplicationContext(appContext);
|
||||
|
||||
EvaluationContext ctx = handler.createEvaluationContext(
|
||||
mock(Authentication.class), mock(FilterInvocation.class));
|
||||
ExpressionParser parser = handler.getExpressionParser();
|
||||
assertThat(parser.parseExpression("@authorityDefaults.getRolePrefix() == 'ROL_'").getValue(
|
||||
ctx, Boolean.class)).isTrue();
|
||||
assertThat(parser.parseExpression("@authorityDefaults.rolePrefix == 'ROL_'").getValue(ctx,
|
||||
Boolean.class)).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
|
|||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.internal.WhiteboxImpl;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
|
@ -43,11 +46,13 @@ import org.springframework.security.authentication.BadCredentialsException;
|
|||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.concurrent.DelegatingSecurityContextRunnable;
|
||||
import org.springframework.security.config.GrantedAuthorityDefaults;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -67,6 +72,7 @@ import static org.powermock.api.mockito.PowerMockito.when;
|
|||
*
|
||||
* @author Ben Alex
|
||||
* @author Rob Winch
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest(ClassUtils.class)
|
||||
|
@ -195,7 +201,7 @@ public class SecurityContextHolderAwareRequestFilterTests {
|
|||
|
||||
// SEC-2296
|
||||
@Test
|
||||
public void loginWithExstingUser() throws Exception {
|
||||
public void loginWithExistingUser() throws Exception {
|
||||
TestingAuthenticationToken expectedAuth = new TestingAuthenticationToken("user",
|
||||
"password", "ROLE_USER");
|
||||
when(this.authenticationManager
|
||||
|
@ -415,4 +421,31 @@ public class SecurityContextHolderAwareRequestFilterTests {
|
|||
|
||||
return this.requestCaptor.getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultRolePrefix() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(FilterConfiguration.class);
|
||||
context.refresh();
|
||||
|
||||
SecurityContextHolderAwareRequestFilter filter = context.getBean(SecurityContextHolderAwareRequestFilter.class);
|
||||
GrantedAuthorityDefaults authorityDefaults = (GrantedAuthorityDefaults) ReflectionTestUtils.getField(filter, "rolePrefix");
|
||||
assertThat(authorityDefaults.getRolePrefix()).isEqualTo("ROL_");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class FilterConfiguration {
|
||||
|
||||
@Bean
|
||||
public GrantedAuthorityDefaults authorityDefaults() {
|
||||
return new GrantedAuthorityDefaults("ROL_");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityContextHolderAwareRequestFilter requestFilter() {
|
||||
return new SecurityContextHolderAwareRequestFilter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue