package auth; import auth.models.Token; import auth.models.User; import auth.types.RoleType; import com.avaje.ebean.Ebean; import exceptions.PoseidonException; import models.CoordinateFormat; import models.UserPreferenceModel; import org.slf4j.LoggerFactory; import play.mvc.Http; import service.PoseidonPropertyService; import service.PoseidonService; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.directory.*; import java.util.Date; import java.util.List; import java.util.Properties; public class LDAPAuthenticator extends Authenticator { public static final String NAMING_EXCEPTION_MESSAGE = "En feil oppstod ved innlogging, vennligst prøv igjen senere"; private static org.slf4j.Logger log = LoggerFactory.getLogger(LDAPAuthenticator.class); @Override public Token authenticate(Authentication anAuthentication) { if (GrantType.LDAP != anAuthentication.getGrantType()) { return null; } LDAPAuthentication authentication = (LDAPAuthentication) anAuthentication; String username = authentication.getUsername(); String fullName = validatePasswordAndGetName(username, authentication.getPassword()); if (fullName.length() > 0) { User user = User.findByUsername(username); if (user == null) { user = new User(); user.username = username; user.name = fullName; user.isActive = true; user.role = RoleType.READWRITE; user.createdBy = user.username; user.created = new Date(PoseidonService.getNow().toDate().getTime()); user.preferences = new UserPreferenceModel(); user.preferences.coordinateFormat = CoordinateFormat.DEGREES_MINUTES_SECONDS; user.preferences.showGrid = true; Ebean.save(user); } List<String> invoicingUsers = PoseidonPropertyService.getStringListProperty("invoicing.usernames"); if ( invoicingUsers.contains(username)){ user.role = RoleType.INVOICING; Ebean.update(user); } Token token = new Token(user, GrantType.LDAP); Ebean.save(token); return token; } else { return null; } } private String validatePasswordAndGetName(String username, String password) { String result = ""; String url = PoseidonPropertyService.getProperty("ldap.serverurl"); String baseDN = PoseidonPropertyService.getProperty("ldap.basedn"); String ou = PoseidonPropertyService.getProperty("ldap.ou"); String principalName = "uid=" + username.trim() + "," + ou + baseDN; log.debug("Logging in " + principalName); String domainName = PoseidonPropertyService.getProperty("ldap.domain"); String socketFactory = PoseidonPropertyService.getProperty("ldap.factory.socket"); if (domainName == null || "".equals(domainName)) { int delim = principalName.indexOf('@'); domainName = principalName.substring(delim + 1); } Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); props.put(Context.PROVIDER_URL, url); props.put(Context.SECURITY_PRINCIPAL, principalName); props.put(Context.SECURITY_CREDENTIALS, password); if (url.toUpperCase().startsWith("LDAPS://")) { props.put(Context.SECURITY_PROTOCOL, "ssl"); // props.put(Context.SECURITY_AUTHENTICATION, "simple"); props.put("java.naming.ldap.factory.socket", socketFactory); } try { DirContext context = new InitialDirContext(props); // just need to get the context to verify credentials Attributes attributes = context.getAttributes(principalName); result = (String) attributes.get("cn").get(); // common name log.debug( principalName + " logged in with real name" + result); } catch (NamingException e) { throw new PoseidonException(Http.Status.INTERNAL_SERVER_ERROR, NAMING_EXCEPTION_MESSAGE,e); } return result; } /** * Create "DC=sub,DC=mydomain,DC=com" string * * @param domainName sub.mydomain.com * @return */ private static String toDC(String domainName) { StringBuilder buf = new StringBuilder(); for (String token : domainName.split("\\.")) { if (token.length() == 0) continue; if (buf.length() > 0) buf.append(","); buf.append("DC=").append(token); } return buf.toString(); } }