Basic LDAP Authentication added on login form.

* It's needed that users exist in database too.

FEA: ItEr74S09LdapAuhentication
This commit is contained in:
Cristina Alvarino 2011-05-20 13:56:11 +02:00 committed by Manuel Rego Casasnovas
parent eaf17f75b9
commit 7f42d8a721
6 changed files with 474 additions and 60 deletions

View file

@ -212,6 +212,32 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core-tiger</artifactId>
</dependency>
<!-- Spring Dependency LDAP -->
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core-tiger</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-odm</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-ldif-core</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-ldif-batch</artifactId>
<version>1.3.1.RELEASE</version>
</dependency>
<!-- AspectJ (required by Spring Security) -->
<dependency>
<groupId>org.aspectj</groupId>

View file

@ -0,0 +1,108 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 ComtecSF S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.users.services;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.security.AuthenticationException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.providers.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
/**
* An extending from AbstractUserDetailsAuthenticationProvider class which is
* used to implement the authentication against LDAP.
*
* In the future this provider will implement all the process explained in
* <https
* ://wiki.navalplan.org/twiki/bin/view/NavalPlan/AnA04S06LdapAuthentication>
*
* At this time it authenticates user against LDAP and then searches it in BD to
* use the BD user in application.
*
* @author Ignacio Diaz <ignacio.diaz@comtecsf.es>
* @author Cristina Alvarino <cristina.alvarino@comtecsf.es>
*
*/
public class LDAPCustomAuthenticationProvider extends
AbstractUserDetailsAuthenticationProvider {
// Template to search in LDAP
private LdapTemplate ldapTemplate;
// Place in LDAP where username is
private String userId;
private UserDetailsService userDetailsService;
@Override
protected void additionalAuthenticationChecks(UserDetails arg0,
UsernamePasswordAuthenticationToken arg1)
throws AuthenticationException {
// No needed at this time
}
@Override
public UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
// Tests if the user is in LDAP, if not, throws a new
// AuthenticationException
if (!(ldapTemplate.authenticate(DistinguishedName.EMPTY_PATH,
new EqualsFilter(userId, username).toString(), authentication
.getCredentials().toString()))) {
throw new BadCredentialsException("User is not in LDAP.");
} else {
// Gets and returns user from DB once authenticated against LDAP
return getUserDetailsService().loadUserByUsername(username);
}
}
// Getters and setters
public LdapTemplate getLdapTemplate() {
return ldapTemplate;
}
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public void setUserDetailsService(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
public UserDetailsService getUserDetailsService() {
return userDetailsService;
}
}

View file

@ -0,0 +1,95 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 ComtecSF S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.users.services;
import static org.navalplanner.web.I18nHelper._;
import java.util.Set;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.scenarios.bootstrap.PredefinedScenarios;
import org.navalplanner.business.scenarios.entities.Scenario;
import org.navalplanner.business.users.daos.IUserDAO;
import org.navalplanner.business.users.entities.User;
import org.navalplanner.business.users.entities.UserRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
/**
* A Class which is used to implement the UserDetailsService interfaces
*
* At this time it takes values from authenticated user (LDAP or DB) and gets
* from DB the user properties.
*
* @author Ignacio Diaz <ignacio.diaz@comtecsf.es>
* @author Cristina Alvarino <cristina.alvarino@comtecsf.es>
*
*/
public class LDAPUserDetailsService implements UserDetailsService {
@Autowired
private IUserDAO userDAO;
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String loginName)
throws UsernameNotFoundException, DataAccessException {
User user;
try {
user = userDAO.findByLoginName(loginName);
} catch (InstanceNotFoundException e) {
throw new UsernameNotFoundException(_("User with login name "
+ "'{0}': not found", loginName));
}
Scenario scenario = user.getLastConnectedScenario();
if (scenario == null) {
scenario = PredefinedScenarios.MASTER.getScenario();
}
return new CustomUser(user.getLoginName(), user.getPassword(),
!user.isDisabled(), true, // accountNonExpired
true, // credentialsNonExpired
true, // accountNonLocked
getGrantedAuthorities(user.getAllRoles()), scenario);
}
private GrantedAuthority[] getGrantedAuthorities(Set<UserRole> roles) {
GrantedAuthority[] grantedAuthorities = new GrantedAuthority[roles
.size()];
int i = 0;
for (UserRole r : roles) {
grantedAuthorities[i++] = new GrantedAuthorityImpl(r.name());
}
return grantedAuthorities;
}
}

View file

@ -1,76 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<!--
NOTE: see http://static.springsource.org/spring-security/site/docs/2.0.x/apidocs/org/springframework/security/vote/AuthenticatedVoter.html
for an explanation of the meaning of IS_AUTHENTICATED_ANONYMOUSLY and IS_AUTHENTICATED_FULLY.
-->
<!-- NOTE: see http://static.springsource.org/spring-security/site/docs/2.0.x/apidocs/org/springframework/security/vote/AuthenticatedVoter.html
for an explanation of the meaning of IS_AUTHENTICATED_ANONYMOUSLY and IS_AUTHENTICATED_FULLY. -->
<http auto-config="true" realm="NavalPlan Web Application" >
<http auto-config="true" realm="NavalPlan Web Application">
<!-- Web services -->
<intercept-url pattern="/ws/rest/**" access="ROLE_WS_READER" method="GET" />
<intercept-url pattern="/ws/rest/**" access="ROLE_WS_WRITER" method="POST" />
<intercept-url pattern="/ws/rest/**" access="ROLE_WS_WRITER" method="PUT" />
<intercept-url pattern="/ws/rest/**" access="ROLE_WS_READER"
method="GET" />
<intercept-url pattern="/ws/rest/**" access="ROLE_WS_WRITER"
method="POST" />
<intercept-url pattern="/ws/rest/**" access="ROLE_WS_WRITER"
method="PUT" />
<!-- Web application -->
<intercept-url pattern="/common/img/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/planner/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/callback/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/zkau/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/help/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/layout/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/layout/timeout.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- Web application -->
<intercept-url pattern="/common/img/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/css/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/planner/css/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/callback/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/zkau/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/help/**"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/layout/login.zul"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/layout/timeout.zul"
access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/advance/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/resources/criterions/**" access="ROLE_ADMINISTRATION"/>
<intercept-url pattern="/resources/criterions/**"
access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/calendars/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/labels/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/materials/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/costcategories/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/common/configuration.zul" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/costcategories/**"
access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/common/configuration.zul"
access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/qualityforms/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/users/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/externalcompanies/**" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/workreports/workReportTypes.zul" access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/externalcompanies/**"
access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/workreports/workReportTypes.zul"
access="ROLE_ADMINISTRATION" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
<form-login login-page="/common/layout/login.zul" authentication-failure-url="/common/layout/login.zul?login_error=true"/>
<form-login login-page="/common/layout/login.zul"
authentication-failure-url="/common/layout/login.zul?login_error=true" />
</http>
<!--
Beans used by Spring Security (current configuration assumes users
are registered in the database).
-->
<beans:bean id="passwordEncoder" class="org.springframework.security.providers.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="512"/>
</beans:bean>
<beans:bean id="saltSource" class="org.springframework.security.providers.dao.salt.ReflectionSaltSource"
p:userPropertyToUse="username"/>
<beans:bean id="authenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider"
<!-- Beans used by Spring Security (current configuration assumes users
are registered in the database). <beans:bean id="passwordEncoder" class="org.springframework.security.providers.encoding.ShaPasswordEncoder">
<beans:constructor-arg value="512"/> </beans:bean> <beans:bean id="saltSource"
class="org.springframework.security.providers.dao.salt.ReflectionSaltSource"
p:userPropertyToUse="username"/> <beans:bean id="authenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider"
p:passwordEncoder-ref="passwordEncoder" p:saltSource-ref="saltSource" p:userDetailsService-ref="dbUserDetailsService">
<custom-authentication-provider/>
<custom-authentication-provider/> </beans:bean> -->
<!-- Beans used by the NavalPlan Web application when users are registered
in the database. When users are registered externally (e.g. in a LDAP server),
these lines may be commented. <beans:bean id="dbUserDetailsService" class="org.navalplanner.web.users.services.DBUserDetailsService"/>
<beans:bean id="dbPasswordEncoderService" class="org.navalplanner.web.users.services.DBPasswordEncoderService"
p:passwordEncoder-ref="passwordEncoder" p:saltSource-ref="saltSource"/> <beans:bean
id="usersBootstrapInDB" class="org.navalplanner.web.users.bootstrap.UsersBootstrapInDB"
p:dbPasswordEncoderService-ref="dbPasswordEncoderService"/> -->
<!-- Beans used by the NavalPlan Web Application when users are registerd
in LDAP. At this moment users MUST be also in database with same username.
This will be changed in the near future. the url, base, userDN and password
properties must be set with the proper values -->
<beans:bean id="contextSource"
class="org.springframework.ldap.core.support.LdapContextSource"
p:url="ldap://localhost:389" p:base="dc=example,dc=org"
p:userDn="cn=admin,dc=example,dc=org" p:password="admin">
</beans:bean>
<!--
Beans used by the NavalPlan Web application when users are
registered in the database. When users are registered externally
(e.g. in a LDAP server), these lines may be commented.
-->
<beans:bean id="dbUserDetailsService" class="org.navalplanner.web.users.services.DBUserDetailsService"/>
<beans:bean id="ldapTemplate"
class="org.springframework.ldap.core.LdapTemplate"
p:contextSource-ref="contextSource">
</beans:bean>
<beans:bean id="dbPasswordEncoderService" class="org.navalplanner.web.users.services.DBPasswordEncoderService"
p:passwordEncoder-ref="passwordEncoder" p:saltSource-ref="saltSource"/>
<!-- This authentication provider will make possible all the login process
when an LDAP is used. Also will allow authenticate users in database. The
property strUserId must be set with the proper value. It represents the property
of the user in LDAP which will be used to check the username. -->
<beans:bean id="authenticationProvider"
class="org.navalplanner.web.users.services.LDAPCustomAuthenticationProvider"
p:userDetailsService-ref="ldapUserDetailsService"
p:ldapTemplate-ref="ldapTemplate" p:userId="uid">
<custom-authentication-provider />
</beans:bean>
<beans:bean id="usersBootstrapInDB" class="org.navalplanner.web.users.bootstrap.UsersBootstrapInDB"
p:dbPasswordEncoderService-ref="dbPasswordEncoderService"/>
<!-- This bean is used to implement UserDetailsService with LDAP authentication
Provider. -->
<beans:bean id="ldapUserDetailsService"
class="org.navalplanner.web.users.services.LDAPUserDetailsService" />
</beans:beans>

View file

@ -0,0 +1,125 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 ComtecSF S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.test.users.services;
import static org.junit.Assert.assertEquals;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.navalplanner.web.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE;
import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import static org.navalplanner.web.test.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE;
import java.util.HashSet;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.scenarios.bootstrap.IScenariosBootstrap;
import org.navalplanner.business.users.entities.UserRole;
import org.navalplanner.web.users.bootstrap.IUsersBootstrapInDB;
import org.navalplanner.web.users.bootstrap.MandatoryUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
*
* Tests for <code>LDAPUserDetailsService</code>.
*
* @author Ignacio Diaz <ignacio.diaz@comtecsf.es>
* @author Cristina Alvarino <cristina.alvarino@comtecsf.es>
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_FILE,
WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE })
@Transactional
public class LDAPUserDetailsServiceTest {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private IUsersBootstrapInDB usersBootstrap;
@Autowired
private IScenariosBootstrap scenariosBootstrap;
@Autowired
private IAdHocTransactionService transactionService;
@Before
public void loadScenariosBootsrap() {
/*
* the required data is loaded in another transaction because if it's
* loaded on the same transaction the added scenario could not be
* retrieved from PredefinedScenario. This happened when executing all
* tests. If you execute this test in isolation this problem doesn't
* happen
*/
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
scenariosBootstrap.loadRequiredData();
return null;
}
});
}
@Test
public void testLoadUserByUsername() {
usersBootstrap.loadRequiredData();
for (MandatoryUser u : MandatoryUser.values()) {
UserDetails userDetails = userDetailsService.loadUserByUsername(u
.getLoginName());
assertEquals(u.getLoginName(), userDetails.getUsername());
assertEquals(u.getInitialRoles(), getUserRoles(userDetails));
}
}
private Set<UserRole> getUserRoles(UserDetails userDetails) {
Set<UserRole> userRoles = new HashSet<UserRole>();
for (GrantedAuthority a : userDetails.getAuthorities()) {
userRoles.add(UserRole.valueOf(a.getAuthority()));
}
return userRoles;
}
}

View file

@ -1,23 +1,52 @@
<?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:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="passwordEncoder" class="org.springframework.security.providers.encoding.ShaPasswordEncoder">
<constructor-arg value="512"/>
<bean id="passwordEncoder"
class="org.springframework.security.providers.encoding.ShaPasswordEncoder">
<constructor-arg value="512" />
</bean>
<bean id="saltSource" class="org.springframework.security.providers.dao.salt.ReflectionSaltSource"
p:userPropertyToUse="username"/>
<bean id="saltSource"
class="org.springframework.security.providers.dao.salt.ReflectionSaltSource"
p:userPropertyToUse="username" />
<!-- <bean id="dbUserDetailsService" class="org.navalplanner.web.users.services.DBUserDetailsService"/> -->
<bean id="dbPasswordEncoderService"
class="org.navalplanner.web.users.services.DBPasswordEncoderService"
p:passwordEncoder-ref="passwordEncoder" p:saltSource-ref="saltSource" />
<bean id="dbUserDetailsService" class="org.navalplanner.web.users.services.DBUserDetailsService"/>
<bean id="usersBootstrapInDB"
class="org.navalplanner.web.users.bootstrap.UsersBootstrapInDB"
p:dbPasswordEncoderService-ref="dbPasswordEncoderService" />
<bean id="dbPasswordEncoderService" class="org.navalplanner.web.users.services.DBPasswordEncoderService"
p:passwordEncoder-ref="passwordEncoder" p:saltSource-ref="saltSource"/>
<!-- Beans used by the NavalPlan Web Application when users are registerd
in LDAP. At this moment users MUST be also in database with same username.
This will be changed in the near future. the url, base, userDN and password
properties must be set with the proper values -->
<bean id="contextSource"
class="org.springframework.ldap.core.support.LdapContextSource"
p:url="ldap://localhost:389" p:base="dc=example,dc=org"
p:userDn="cn=admin,dc=example,dc=org" p:password="admin">
</bean>
<bean id="usersBootstrapInDB" class="org.navalplanner.web.users.bootstrap.UsersBootstrapInDB"
p:dbPasswordEncoderService-ref="dbPasswordEncoderService"/>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"
p:contextSource-ref="contextSource">
</bean>
</beans>
<!-- This authentication provider will make possible all the login process
when an LDAP is used. Also will allow authenticate users in database. The
property strUserId must be set with the proper value. It represents the property
of the user in LDAP which will be used to check the username. -->
<bean id="authenticationProvider"
class="org.navalplanner.web.users.services.LDAPCustomAuthenticationProvider"
p:userDetailsService-ref="ldapUserDetailsService"
p:ldapTemplate-ref="ldapTemplate" p:userId="uid">
</bean>
<!-- This bean is used to implement UserDetailsService with LDAP authentication
Provider. -->
<bean id="ldapUserDetailsService"
class="org.navalplanner.web.users.services.LDAPUserDetailsService" />
</beans>