package com.autentia.tnt.manager.security; import com.autentia.tnt.businessobject.User; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.ldap.LdapAuthenticationProvider; import org.acegisecurity.providers.ldap.LdapAuthenticator; import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.ldap.LdapUserDetails; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; public class LdapCustomAuthenticationProvider extends LdapAuthenticationProvider { private UserDetailsService userDetailsService; private static final Log log = LogFactory.getLog(LdapCustomAuthenticationProvider.class); public LdapCustomAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) { super(authenticator, authoritiesPopulator); } public void setUserDetailsService(UserDetailsService userDetailsService) { this.userDetailsService = userDetailsService; } @Override protected UserDetails createUserDetails(LdapUserDetails ldapUser, String username, String password) { Principal principalFromDB = (Principal) userDetailsService.loadUserByUsername(username); return mergeUsers(ldapUser, principalFromDB, password); } protected Principal mergeUsers(LdapUserDetails ldapUser, Principal principalFromDB, String password) { User user = principalFromDB.getUser(); user.setDn(ldapUser.getDn()); user.setLdapName(ldapUser.getDn().replace(",dc=autentia,dc=com", "")); user.setLdapPassword(password); user.setActive(ldapUser.isEnabled()); user.setPasswordExpired(checkExpiredPassword(ldapUser.getAttributes())); user.setResetPassword(checkResetPassword(ldapUser.getAttributes())); return new Principal(user, user.getLdapPassword(), principalFromDB.getAuthorities()); } protected Boolean checkExpiredPassword(Attributes attributes) { return attributes.get(LdapAttributes.PWD_GRACE_LOGIN) != null; } protected Boolean checkResetPassword(Attributes attributes) { Boolean result = Boolean.FALSE; final Attribute pwdReset = attributes.get(LdapAttributes.PASSWORD_RESET); if (pwdReset != null) { try { result = Boolean.valueOf((String) pwdReset.get()); } catch (NamingException e) { log.error("Incorrect value - " + pwdReset); } } return result; } @Override protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) { UserDetails userDetails = null; try { userDetails = super.retrieveUser(username, authentication); } catch (AuthenticationServiceException authenticationServiceException) { if (authenticationServiceException.getMessage().contains("LDAP: error code 50 - Operations are restricted to bind/unbind/abandon/StartTLS/modify password")) { userDetails = new PrincipalResetPassword(username, authentication.getCredentials().toString()); } else { throw authenticationServiceException; } } return userDetails; } }