diff --git a/navalplanner-webapp/pom.xml b/navalplanner-webapp/pom.xml
index 32070b8dd..6660f8828 100644
--- a/navalplanner-webapp/pom.xml
+++ b/navalplanner-webapp/pom.xml
@@ -212,6 +212,32 @@
org.springframework.security
spring-security-core-tiger
+
+
+ org.springframework.ldap
+ spring-ldap-core
+ 1.3.1.RELEASE
+
+
+ org.springframework.ldap
+ spring-ldap-core-tiger
+ 1.3.1.RELEASE
+
+
+ org.springframework.ldap
+ spring-ldap-odm
+ 1.3.1.RELEASE
+
+
+ org.springframework.ldap
+ spring-ldap-ldif-core
+ 1.3.1.RELEASE
+
+
+ org.springframework.ldap
+ spring-ldap-ldif-batch
+ 1.3.1.RELEASE
+
org.aspectj
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/users/services/LDAPCustomAuthenticationProvider.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/users/services/LDAPCustomAuthenticationProvider.java
new file mode 100644
index 000000000..2d79ab930
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/users/services/LDAPCustomAuthenticationProvider.java
@@ -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 .
+ */
+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
+ *
+ *
+ * At this time it authenticates user against LDAP and then searches it in BD to
+ * use the BD user in application.
+ *
+ * @author Ignacio Diaz
+ * @author Cristina Alvarino
+ *
+ */
+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;
+ }
+
+}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/users/services/LDAPUserDetailsService.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/users/services/LDAPUserDetailsService.java
new file mode 100644
index 000000000..d3068c7db
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/users/services/LDAPUserDetailsService.java
@@ -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 .
+ */
+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
+ * @author Cristina Alvarino
+ *
+ */
+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 roles) {
+
+ GrantedAuthority[] grantedAuthorities = new GrantedAuthority[roles
+ .size()];
+ int i = 0;
+
+ for (UserRole r : roles) {
+ grantedAuthorities[i++] = new GrantedAuthorityImpl(r.name());
+ }
+
+ return grantedAuthorities;
+
+ }
+
+}
diff --git a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-security-config.xml b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-security-config.xml
index 5004d9e8f..5f3ec2d7f 100644
--- a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-security-config.xml
+++ b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-security-config.xml
@@ -1,76 +1,107 @@
-
+
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
+
-
+ -->
+
+
+
-
-
+
+
-
+
+
+
+
-
+
+
diff --git a/navalplanner-webapp/src/test/java/org/navalplanner/web/test/users/services/LDAPUserDetailsServiceTest.java b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/users/services/LDAPUserDetailsServiceTest.java
new file mode 100644
index 000000000..5a69a15c2
--- /dev/null
+++ b/navalplanner-webapp/src/test/java/org/navalplanner/web/test/users/services/LDAPUserDetailsServiceTest.java
@@ -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 .
+ */
+
+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 LDAPUserDetailsService.
+ *
+ * @author Ignacio Diaz
+ * @author Cristina Alvarino
+ *
+ */
+
+@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() {
+ @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 getUserRoles(UserDetails userDetails) {
+
+ Set userRoles = new HashSet();
+
+ for (GrantedAuthority a : userDetails.getAuthorities()) {
+ userRoles.add(UserRole.valueOf(a.getAuthority()));
+ }
+
+ return userRoles;
+
+ }
+
+}
diff --git a/navalplanner-webapp/src/test/resources/navalplanner-webapp-spring-security-config-test.xml b/navalplanner-webapp/src/test/resources/navalplanner-webapp-spring-security-config-test.xml
index 3566ec820..6dc36d664 100644
--- a/navalplanner-webapp/src/test/resources/navalplanner-webapp-spring-security-config-test.xml
+++ b/navalplanner-webapp/src/test/resources/navalplanner-webapp-spring-security-config-test.xml
@@ -1,23 +1,52 @@
-
-
+
+
-
+
+
+
-
+
-
+
+
+
-
+
+
-
\ No newline at end of file
+
+
+
+
+
+
+