diff --git a/src/main/java/info/bukova/isspst/security/AuthPopulator.java b/src/main/java/info/bukova/isspst/security/AuthPopulator.java index 5701a609..2191077f 100644 --- a/src/main/java/info/bukova/isspst/security/AuthPopulator.java +++ b/src/main/java/info/bukova/isspst/security/AuthPopulator.java @@ -1,15 +1,13 @@ package info.bukova.isspst.security; import info.bukova.isspst.Constants; -import info.bukova.isspst.data.Role; import info.bukova.isspst.data.User; +import info.bukova.isspst.services.users.LdapUserImporter; import info.bukova.isspst.services.users.RoleService; import info.bukova.isspst.services.users.UserService; import java.util.Collection; -import javax.naming.NamingException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ldap.core.DirContextOperations; @@ -38,36 +36,10 @@ public class AuthPopulator implements LdapAuthoritiesPopulator { Logger logger = LoggerFactory.getLogger(AuthPopulator.class); logger.info("Importing user from LDAP"); - user = new User(); - user.setUsername(login); - Role role = roleService.getRoleByAuthority(Constants.ROLE_USER); - user.addAuthority(role); - - if (userData.attributeExists("givenName")) { - try { - user.setFirstName(userData.getAttributes().get("givenName").get().toString()); - } catch (NamingException e1) { - logger.info("LDAP object has no 'givenName' attribute"); - } - } - if (userData.attributeExists("sn")) { - try { - user.setLastName(userData.getAttributes().get("sn").get().toString()); - } catch (NamingException e1) { - logger.info("LDAP object has no 'sn' attribute"); - } - } - if (userData.attributeExists("mail")) { - try { - user.setEmail(userData.getAttributes().get("mail").get().toString()); - } catch (NamingException e1) { - logger.info("LDAP object has no 'mail' attribute"); - } - } + LdapUserImporter importer = new LdapUserImporter(userService); + importer.importUser(login, userData, roleService.getRoleByAuthority(Constants.ROLE_USER)); - userService.grantAdmin(); - userService.add(user); - userService.removeAccess(); + user = (User) userService.loadUserByUsername(login); } return user != null ? user.getAuthorities() : null; diff --git a/src/main/java/info/bukova/isspst/services/users/AdUserCtxMapper.java b/src/main/java/info/bukova/isspst/services/users/AdUserCtxMapper.java new file mode 100644 index 00000000..b0450f09 --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/users/AdUserCtxMapper.java @@ -0,0 +1,59 @@ +package info.bukova.isspst.services.users; + +import info.bukova.isspst.Constants; +import info.bukova.isspst.data.User; + +import java.util.Collection; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ldap.core.DirContextAdapter; +import org.springframework.ldap.core.DirContextOperations; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider; +import org.springframework.security.ldap.userdetails.UserDetailsContextMapper; + +/** + * Mapovač doménových uživatelů Active Directory na uživatele aplikace. Pokud uživatel není v aplikační databází, + * importu je se tam pomoci {@link LdapUserImporter}. Tento objekt se předává do {@link ActiveDirectoryLdapAuthenticationProvider}. + * + * @author pepa + * + */ +public class AdUserCtxMapper implements UserDetailsContextMapper { + + private UserService userService; + private RoleService roleService; + + private final static Logger logger = LoggerFactory.getLogger(AdUserCtxMapper.class); + + public AdUserCtxMapper(UserService userService, RoleService roleService) { + this.userService = userService; + this.roleService = roleService; + } + + @Override + public UserDetails mapUserFromContext(DirContextOperations userData, + String username, Collection authorities) { + + try { + User user = (User) userService.loadUserByUsername(username); + return user; + } catch (UsernameNotFoundException e) { + logger.info("Importing user from Active Directory"); + LdapUserImporter importer = new LdapUserImporter(userService); + importer.importUser(username, userData, roleService.getRoleByAuthority(Constants.ROLE_USER)); + + return userService.loadUserByUsername(username); + } + } + + @Override + public void mapUserToContext(UserDetails user, DirContextAdapter ctx) { + throw new UnsupportedOperationException("LdapUserDetailsMapper only supports reading from a context. Please" + + "use a subclass if mapUserToContext() is required."); + } + +} diff --git a/src/main/java/info/bukova/isspst/services/users/LdapUserImporter.java b/src/main/java/info/bukova/isspst/services/users/LdapUserImporter.java new file mode 100644 index 00000000..7da73858 --- /dev/null +++ b/src/main/java/info/bukova/isspst/services/users/LdapUserImporter.java @@ -0,0 +1,90 @@ +package info.bukova.isspst.services.users; + +import info.bukova.isspst.data.Role; +import info.bukova.isspst.data.User; +import info.bukova.isspst.data.UsersAddress; + +import javax.naming.NamingException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ldap.core.DirContextOperations; + +/** + * Pomocná třída pro import uživatele z LDAP serveru (nebo Active Directory) do databáze aplikace + * + * @author pepa + * + */ +public class LdapUserImporter { + + private UserService userService; + private final static Logger logger = LoggerFactory.getLogger(LdapUserImporter.class); + + public LdapUserImporter(UserService userService) { + this.userService = userService; + } + + /** + * Provede import uživatele z LDAP do aplikační databáze + * + * @param login - login uživatele + * @param userData - objekt reprezentujízí data z LDAP + * @param defaultRole - role, která má být přidělena novému uživateli + */ + public void importUser(String login, DirContextOperations userData, Role defaultRole) { + User user = new User(); + user.setUsername(login); + user.addAuthority(defaultRole); + + if (userData.attributeExists("givenName")) { + try { + user.setFirstName(userData.getAttributes().get("givenName").get().toString()); + } catch (NamingException e1) { + logger.info("LDAP object has no 'givenName' attribute"); + } + } + if (userData.attributeExists("sn")) { + try { + user.setLastName(userData.getAttributes().get("sn").get().toString()); + } catch (NamingException e1) { + logger.info("LDAP object has no 'sn' attribute"); + } + } + if (userData.attributeExists("mail")) { + try { + user.setEmail(userData.getAttributes().get("mail").get().toString()); + user.setNotify(true); + } catch (NamingException e1) { + logger.info("LDAP object has no 'mail' attribute"); + } + } + + UsersAddress address = new UsersAddress(); + boolean hasAddress = false; + + if (userData.attributeExists("streetAddress")) { + address.setStreet(userData.getStringAttribute("streetAddress")); + hasAddress = true; + } + if (userData.attributeExists("l")) { + address.setCity(userData.getStringAttribute("l")); + hasAddress = true; + } + if (userData.attributeExists("postalCode")) { + address.setZipCode(userData.getStringAttribute("postalCode")); + hasAddress = true; + } + + if (hasAddress) { + user.setAddress(address); + } + + user.setEnabled(true); + + userService.grantAdmin(); // povýšit práva pro toto vlákno + userService.add(user); + userService.removeAccess(); + } + +} diff --git a/src/main/webapp/WEB-INF/ad.properties b/src/main/webapp/WEB-INF/ad.properties new file mode 100644 index 00000000..ca41b75a --- /dev/null +++ b/src/main/webapp/WEB-INF/ad.properties @@ -0,0 +1,2 @@ +ad.domain=bukova.net +ad.ldapUrl=ldap://192.168.25.110/ \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/spring/ad-auth.xml b/src/main/webapp/WEB-INF/spring/ad-auth.xml new file mode 100644 index 00000000..d476b509 --- /dev/null +++ b/src/main/webapp/WEB-INF/spring/ad-auth.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/spring/root-context.xml b/src/main/webapp/WEB-INF/spring/root-context.xml index abc4569c..9ece4018 100644 --- a/src/main/webapp/WEB-INF/spring/root-context.xml +++ b/src/main/webapp/WEB-INF/spring/root-context.xml @@ -28,6 +28,7 @@ /WEB-INF/ldap.properties /WEB-INF/mail.properties /WEB-INF/gmail.properties + /WEB-INF/ad.properties @@ -137,9 +138,11 @@ + + -