What is the equivalent in java config of this XML authentication-manager config?
<authentication-manager alias="authenticationManager"> ... </authentication-manager>
What i need exactly is convert this xml config to java config :
`<security:authentication-manager alias="authenticationManagerLdap">
<security:authentication-provider ref="ldapActiveDirectoryAuthProvider"/>
</security:authentication-manager>
<bean id="ldapActiveDirectoryAuthProvider" class="ma.gov.adii.beans.AuthenticationAD">
<constructor-arg value="adii.gov.ma"/>
<constructor-arg value="ldap://addouane.adii.gov.ma:389/"/>
<property name="convertSubErrorCodesToExceptions" value="true" />
<property name="userDetailsContextMapper" ref="manageLoginService" />
</bean>`
My login clas is like this :
public class LoginMBean implements Serializable { #Autowired private AuthenticationManager authenticationManagerLdap;
Thanks
THE ANSWER IS LIKE THIS :
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
#Autowired
void registerProvider(AuthenticationManagerBuilder authLdap) {
authLdap.authenticationProvider(ldapActiveDirectoryAuthProvider());
}
Related
I have multiple authentication managers in the application. I distinguish them by bean name. Part of my xml configuration related to oauth authorization server looks like and it works fine:
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" user-approval-handler-ref="userApprovalHandler" >
<oauth:authorization-code disabled="true" />
<oauth:implicit disabled="false" />
<oauth:refresh-token disabled="false" />
<oauth:client-credentials disabled="false" />
<oauth:password authentication-manager-ref="authenticationManager" />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter" resource-id="resource-id" token-services-ref="tokenServices" />
<sec:authentication-manager id="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="oauthClientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
I'm trying to move it to Java based configuration (in some SecurityConfig class), without lack so far. I've tried something like:
#Configuration
#EnableAuthorizationServer
protected static class OAuth2AuthConfig extends AuthorizationServerConfigurerAdapter {
#Resource(name = "authenticationManager")
private AuthenticationManager authenticationManager;
#Resource
private OAuth2AuthenticationEntryPoint authenticationEntryPoint;
#Resource(name = "clientDetails")
private ClientDetailsService clientDetailsService;
#Resource
private TokenStore tokenStore;
#Resource
private TokenStoreUserApprovalHandler userApprovalHandler;
#Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.authenticationEntryPoint(authenticationEntryPoint);
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.userApprovalHandler(userApprovalHandler)
.tokenStore(tokenStore);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.withClientDetails(clientDetailsService);
}
}
#Configuration
#EnableResourceServer
protected static class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {
#Resource
private DefaultTokenServices tokenServices;
#Resource(name = "authenticationManager")
private AuthenticationManager authenticationManager;
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).tokenServices(tokenServices).authenticationManager(authenticationManager);
}
}
however it still complains about multiple authentication managers, although I explicitly set endpoints.authenticationManager(authenticationManager).
With some debugging I can see it tries to configure it within class WebSecurityConfigurerAdapter and it meets multiple authentication manager within authenticationManager(). Am I able to override it or what am I missing?
AuthorizationServer - here there is a way to prevent Spring to fail on
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#authenticationManager by simply overriding method
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerSecurityConfiguration#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder) - explanation
ResourceServer - unfortunately there is no way for similar handling corresponding problem. Best what you can do is decreasing number of instances of global authentication managers to exactly one.
I'm trying to convert our security.xml to JavaConfig
**
* <security:global-method-security
secured-annotations="enabled"
jsr250-annotations="enabled"
access-decision-manager-ref="accessDecisionManager">
</security:global-method-security>
*/
#Configuration
#EnableGlobalMethodSecurity( jsr250Enabled = true, securedEnabled = true )
public class SecurityConfig
{
private UserDetailsService userDetailsService;
/**
* <bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg>
<list>
<bean class="com.myapp.security.access.voter.MyAppRoleVoter">
<property name="rolePrefix" value="" />
</bean>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
*/
#Bean
AccessDecisionManager accessDecisionManager( ) {
return new AffirmativeBased( Collections.singletonList( new MyAppRoleVoter() ) );
}
/**
* <security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="clientDetailsUserService"/>
<security:authentication-provider user-service-ref="principalService">
<security:password-encoder ref="passwordEncoder" />
</security:authentication-provider>
</security:authentication-manager>
*/
#Autowired
void configureGlobal(
final AuthenticationManagerBuilder auth,
#Qualifier( PasswordEncryptionConfig.PASSWORD_ENCODER ) final PasswordEncoder passwordEncoder
) throws Exception {
auth.userDetailsService( userDetailsService ).passwordEncoder( passwordEncoder );
}
#Autowired
public void setUserDetailsService(
#Qualifier( PrincipalService.BEAN_ID ) final UserDetailsService userDetailsService )
{
this.userDetailsService = userDetailsService;
}
}
This exception isn't particularly surprising
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.myapp.config.SecurityConfig.setUserDetailsService(org.springframework.security.core.userdetails.UserDetailsService); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'methodSecurityInterceptor': Requested bean is currently in creation: Is there an unresolvable circular reference?
How can I write my javaconfig so that it does the same thing as the previous XML? (Update: at the time of this writing this is occurring in Spring Security 4.0.4 on Platform BOM 2.0.5)
I implemented the LDAP authentication and authorization using Spring Security in my project. I configured the spring-security.xml and got it running. I am trying to do the same using Java (WebSecurityConfig.java). Can someone guide me on how to do this?
Here is my spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true" >
<security:intercept-url pattern="/main/common" access="hasRole('role.xyz.WebAdmin')"/>
<security:intercept-url pattern="/admincare" access="hasRole('role.xyz.WebAdmin')"/>
<security:form-login
login-page="/auth/login"
authentication-failure-url="/auth/login?error=true"
default-target-url="/main/common"/>
<security:logout
invalidate-session="true"
logout-success-url="/auth/login"
logout-url="/auth/logout"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg name="authenticator">
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="ldapContext" />
<property name="userSearch">
<bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg name="searchBase" value="" />
<constructor-arg name="searchFilter" value="(&(uid={0})(objectclass=person)(ums-account-state=OK))" />
<constructor-arg name="contextSource" ref="ldapContext" />
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="com.gemalto.mobileid.service.UmsLdapAuthoritiesPopulator">
<constructor-arg ref="ldapContext"/>
</bean>
</constructor-arg>
</bean>
<security:ldap-server id="ldapContext" url="ldap://aaa:54389/dc=xxx.com" manager-dn="bbb" manager-password="ccc" />
</beans>
Now, if I want to do same in the JAVA style (in WebSecurityConfig.java) and get rid of the XML, how do I do? I am not so familiar with the APIs provided for this. I started it this way:
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("", "ldap://aaa:54389/dc=xxx.com");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
#Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// Configuration for Redirects, Login-Page and stuff
http
.authorizeRequests()
.antMatchers("/admincare").authenticated()
.and()
.formLogin();
//.loginPage("/auth/login")
//.permitAll();
}
I am not sure how to set the rest of the parameters (as done in XML) in this Java code for the WebSecurityConfig. Any help would be really appreciated
Pls try this :-
#Bean
public BaseLdapPathContextSource contextSource() {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://aaa:54389/dc=xxx.com");
contextSource.setUserDn("bbb");
contextSource.setPassword("ccc");
return contextSource;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.contextSource(contextSource())
.and()
.ldapAuthoritiesPopulator(new UmsLdapAuthoritiesPopulator(contextSource()))
.and()
.userSearchBase("").userSearchFilter("(&(uid={0})(objectclass=person)(ums-account-state=OK))");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/main/common**","/admincare**").hasRole("role.xyz.WebAdmin")
.and().formLogin().loginPage("/auth/login").failureUrl("/auth/login?error=true").defaultSuccessUrl("/main/common")
.and().logout().invalidateHttpSession(true).logoutSuccessUrl("/auth/login").logoutUrl("/auth/logout");
}
I'm trying to use Spring OAuth2 for my rest app.
But looks like I made a mistake and I can find where I did it.
The flow should be:
1. get token from /oauth/token with username and password
2. make request to /security with provided token
MethodSecurityConfig:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Autowired
private SecurityConfiguration securityConfig;
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
OAuth2ServerConfig:
#Configuration
public class OAuth2ServerConfig {
private static final String RESOURCE_ID = "nessnity";
#Configuration
#Order(10)
protected static class UiResourceConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/security")
.and()
.authorizeRequests()
.antMatchers("/security").access("hasRole('USER')");
}
}
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/security/")
.and()
.authorizeRequests()
.antMatchers("/security").access("#oauth2.hasScope('read')");
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private TokenStore tokenStore;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("my-client")
.resourceIds(RESOURCE_ID)
.authorizedGrantTypes("client_credentials")
.authorities("ROLE_CLIENT")
.scopes("read")
.secret("password")
.accessTokenValiditySeconds(60);
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore)
.userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm("sparklr2/client");
}
}
protected static class Stuff {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private TokenStore tokenStore;
#Bean
public ApprovalStore approvalStore() throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
#Bean
#Lazy
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)
public SparklrUserApprovalHandler userApprovalHandler() throws Exception {
SparklrUserApprovalHandler handler = new SparklrUserApprovalHandler();
handler.setApprovalStore(approvalStore());
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
handler.setUseApprovalStore(true);
return handler;
}
}
}
SecurityConfiguration:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("root")
.password("password")
.roles("USER");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/oauth/uncache_approvals", "/oauth/cache_approvals");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().hasRole("USER");
}
}
Problem: when I tried to get token
curl --user root:password --data "grant_type=client_credentials" http://localhost:8080/oauth/token
I got message:
{"error":"invalid_client","error_description":"Bad client
credentials"}
The second question is how to pass username/password in the url params like /oauth/token?username=root&password=password ?
Thanks.
UPDATE
I decided to start from scratch and use xml configuration.
The following configuration works perfect:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<bean id="clientDetails" class="com.nessnity.api.security.OAuthClienDetailsService">
<property name="id" value="testuser"/>
<property name="secretKey" value="secret" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="springsec/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<oauth:authorization-server
client-details-service-ref="clientDetails"
token-services-ref="tokenServices">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials/>
<oauth:password authentication-manager-ref="userAuthenticationManager"/>
</oauth:authorization-server>
<authentication-manager id="userAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customUserAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<bean id="customUserAuthenticationProvider"
class="com.nessnity.api.security.OAuthUserAuthenticationProvider">
</bean>
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="accessTokenValiditySeconds" value="900000000"/>
<property name="clientDetailsService" ref="clientDetails"/>
</bean>
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</bean>
<http pattern="/resources/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false"/>
<intercept-url pattern="/resources/**" method="GET"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<oauth:resource-server id="resourceServerFilter"
resource-id="springsec" token-services-ref="tokenServices"/>
</beans>
I have faced similar for me it worked after doing the following change
In your AuthorizationServerConfiguration class replace
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm("sparklr2/client");
}
with the below code
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
//oauthServer.realm("sparklr2/client");
oauthServer.allowFormAuthenticationForClients();
}
and request should like
/oauth/token?grant_type=password&scope=read+write&client_id=yourclientId&client_secret=secret&username=userName&password=pwd
In your access token request you are using client credentials grant type. OAuth spec says that in case of client_credentials grant type you need to provide base64 encoded client_id:client_secret as Basic Authorization header.
For example if your client_id is google and client_secret is x23r-ss56-rfg8-6yt6, then you need to add these string as google:x23r-ss56-rfg8-6yt6, encode it using Base64 encoder and make request as
curl --header "Authorization: Basic <base64 encoded_string>" --data "grant_type=client_credentials" http://localhost:8080/oauth/token
I currently have my ldap authentication context set up like this:
<ldap-server url="ldap://host/dn"
manager-dn="cn=someuser"
manager-password="somepass" />
<authentication-manager>
<ldap-authentication-provider user-search-filter="(samaccountname={0})"/>
</authentication-manager>
Now, I need to be able to set up a custom authorities mapper (it uses a different ldap server) - so I am assuming I need to set up my ldap-server similar to (http://static.springsource.org/spring-security/site/docs/2.0.x/reference/ldap.html):
<bean id="ldapAuthProvider"
class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userDnPatterns">
<list><value>uid={0},ou=people</value></list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=groups"/>
<property name="groupRoleAttribute" value="ou"/>
</bean>
</constructor-arg>
</bean>
But, how do I reference that 'ldapAuthProvider' to the ldap-server in the security context?
I am also using spring-security 3, so '' does not exist...
What I have done to make it work was simply to add this into the security context:
<authentication-manager>
<authentication-provider ref='ldapAuthProvider'/>
</authentication-manager>
And then, configuring the 'ldapAuthProvider' bean like this:
<bean id="contextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldaps://url/dc=mock,dc=com" />
<property name="userDn" value="cn=username,ou=People,dc=mock,dc=com" />
<property name="password" value="password" />
</bean>
<bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource" />
<property name="userDnPatterns">
<list>
<value>uid={0},ou=People</value>
</list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean
class="com.mock.MyCustomAuthoritiesPopulator">
</bean>
</constructor-arg>
</bean>
With the implementation of MyCustomAuthoritiesPopulator as follows:
public class MyCustomAuthoritiesPopulator implements LdapAuthoritiesPopulator {
public Collection<GrantedAuthority> getGrantedAuthorities(
DirContextOperations arg0, String arg1) {
ArrayList<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
list.add((new SimpleGrantedAuthority("ROLE_USER"));
return list;
}
}
For the record spring configuration is simpler if you use a custom LdapUserDetailsMapper as there's a dedicated parameter user-context-mapper-ref exposed on <ldap-authentication-provider/> which allows you to use the short config style:
<authentication-manager>
<ldap-authentication-provider
user-search-filter="sAMAccountName={0}"
user-search-base="OU=Users"
group-search-filter="(&(objectclass=group)(member={0}))"
group-search-base="OU=Groups"
user-context-mapper-ref="customUserContextMapper" />
</authentication-manager>
<ldap-server url="ldap://url:389/DC=mock,DC=com"
manager-dn="manager"
manager-password="pass" />
Source: http://forum.springsource.org/showthread.php?118845-How-to-modify-Authority-after-loading-it-from-LDAP
On a side note, going the LdapAuthoritiesPopulator route you can also extend DeafultLdapAuthoritiesPopulator and override getAdditionalRoles() rather than implementing the interface directly.
public class MyCustomAuthoritiesPopulator extends
DefaultLdapAuthoritiesPopulator {
#Override
protected Set<GrantedAuthority> getAdditionalRoles(
DirContextOperations user, String username) {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
authorities.add((new SimpleGrantedAuthority("ROLE_USER"));
return authorities;
}
If you want to avoid ugly bean definitions (DefaultSpringSecurityContextSource, LdapAuthenticationProvider, BindAuthenticator,...+100) and use "cool" xml definitions like
<authentication-manager>
<ldap-authentication-provider... />
</authentication-manager>
You can use a BeanPostProcessor. The following example is a costumization of the GrantedAuthoritiesMapper in the AuthenticationProvider:
[context.xml]
<ldap-server id="ldapServer" url="${ldap.url}" manager-dn="${ldap.manager.dn}" manager-password="${ldap.manager.password}"/>
<authentication-manager>
<ldap-authentication-provider user-search-filter="${ldap.userSearch.filter}" user-search-base="${ldap.searchBase}"
group-search-base="${ldap.groupSearchBase}"/>
</authentication-manager>
[UserGrantedAuthoritiesMapper.java]
package com.example.access.ldap;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.stereotype.Component;
#Component
public class UserGrantedAuthoritiesMapper implements GrantedAuthoritiesMapper{
public Collection<? extends GrantedAuthority> mapAuthorities(final Collection<? extends GrantedAuthority> authorities) {
...
return roles;
}
}
[AuthenticationProviderPostProcessor.java]
package com.example.access.ldap;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider;
import org.springframework.stereotype.Component;
#Component
public class AuthenticationProviderPostProcessor implements BeanPostProcessor{
#Autowired
private GrantedAuthoritiesMapper grantedAuthoritiesMapper;
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
#Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if(bean != null && bean instanceof AbstractLdapAuthenticationProvider){
setProviderAuthoritiesMapper((AbstractLdapAuthenticationProvider)bean);
}
return bean;
}
protected void setProviderAuthoritiesMapper(AbstractLdapAuthenticationProvider authenticationProvider){
if(authenticationProvider != null){
authenticationProvider.setAuthoritiesMapper(grantedAuthoritiesMapper);
}
}
}