ucLoginAuthenticateUser

Purpose

Provides an exit to authenticate users outside of ExtraView,

Applies To

User Authentication Methods

Signature

public boolean ucLoginAuthenticateUser (
      String id, 			// the User ID
      String pswd)                      // the password

Notes

Typically used when interfacing with a directory service such as LDAP.

Example

ucLoginAuthenticateUser implements the following custom authentication routine:search the LDAP directory for the uid provided; if only one entry exists, then obtain the uniqueIdentifier attribute and perform the authentication; if multiple entries exist for the same uid, then write to the log and fail the authentication.

    public boolean ucLoginAuthenticateUser (String id, String pswd) {
        boolean authenticated = false;
        Connection con = null;

        // Use this for LDAP Authentication
        SearchLDAP slap = new SearchLDAP();

        try {
            // Error check
            if (id == null || id.trim().length() == 0)
                throw new Exception("Empty user id!");

            if (pswd == null || pswd.trim().length() == 0)
                throw new Exception("Empty user password!");
            
            // For the Admin user configured for ADMIN_USER_ID parameter in 
            // Configuration.properties bypass the custom authentication and 
            // return false. If the CUSTOM_AUTHENTICATION behavior property 
            // is set to HYBRID, then extraview will use the inbuilt authentication
            // after returning from this method.
           
            String adminUserId = Z.config.getConfigValue("ADMIN_USER_ID");
            if(adminUserId !=null && adminUserId.equals(id)){
            	return false;
            }

            // Search the directory for the id provided
            String distinguishedName = searchForDistinguishedName(id);

            // Authenticate user
            DirContext ctx = getContext(distinguishedName.toString(), pswd);

            if (ctx != null) {
                // do a little test to see if we authenticated....
                ctx.lookup("");
                authenticated = true;

                try {
                    // we connected  - upsert the data now
                    con = Z.pool.getConnection();
                    slap.doUpsert(con, ctx, id, true);
                }
                catch (Exception e) {
                    Z.log.writeToLog(Z.log.ERROR, "UPSERT FAILED: " + e);
                    ErrorWriter.write(e, ErrorWriter.ERR);
                }
                finally {
                    ctx.close();
                    if (con != null) Z.pool.close(con);
                }
            }
        } catch (Exception e) {
            Z.log.writeToLog(Z.log.ERROR, "authentication error: " + e);
            ErrorWriter.write(e, ErrorWriter.LOGERR);
        }
        return authenticated;
    }

    /**
     * searchForDistinguishedName searches the LDAP directory for the 
     * given user id and returns the distinguishedName attribute value
     * if only one exists; if multiple entries exist with the same uid, 
     * then write out the info to the log and throw an exception.
     */

    private String searchForDistinguishedName (String uid)
    throws Exception {
        // Get simple directory context for searching
        Hashtable env = new Hashtable();
        env.put(Context.PROVIDER_URL, Z.lu.getInitHost() );
        env.put(Context.INITIAL_CONTEXT_FACTORY, initContextFactory);
        env.put(Context.SECURITY_AUTHENTICATION, securityAuth);
        env.put(Context.SECURITY_PRINCIPAL,Z.lu.getInitMgrDn());
        env.put(Context.SECURITY_CREDENTIALS,Z.lu.getInitPswd());
        DirContext ctx = new InitialDirContext(env);
        
        String primaryKeyAttr = 
               Z.config.getConfigValue("LDAP_PRIMARYKEY");
        String firstNameAttr = 
               Z.config.getConfigValue("LDAP_GIVENNAME");
        String lastNameAttr = 
               Z.config.getConfigValue("LDAP_SURNAME");
        String distinguishedNameAttr = 
               Z.config.getConfigValue("LDAP_DISTINGUISHEDNAME");
        String activeUserFilterAttr = 
               Z.config.getConfigValue("LDAP_USER_FILTER_ATTR");
        String activeUserFilterAttrCriteria = 
               Z.config.getConfigValue("LDAP_USER_FILTER_ATTR_CRITERIA");

        // Prepare for searching
        String filter = "(&("+primaryKeyAttr+"=" + uid + ")("+firstNameAttr+"=*)("
        	+lastNameAttr+"=*)("+activeUserFilterAttr+"=*"
                +activeUserFilterAttrCriteria+"*))";
        SearchControls controls = new SearchControls();
        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        
        // Search directory and collect unique identifiers
        ArrayList distinguishedNames = new ArrayList();
        NamingEnumeration ne = ctx.search(Z.lu.getInitSearchBase(), filter, controls);
        

        while (ne.hasMore() ) {
            SearchResult sr = (SearchResult) ne.next();
            Attributes atts = sr.getAttributes();
            Attribute att = atts.get(distinguishedNameAttr);
            String distinguishedNameString = (String)att.get();
       		distinguishedNames.add(distinguishedNameString);
        }
        ctx.close();
        // Check how many entries were found
        String msg = null;

        if (distinguishedNames.isEmpty() ) {
            msg = "No entry found in LDAP for "+primaryKeyAttr+"=" + uid;
            Z.log.writeToLog(Z.log.WARN, msg);
        }
        else if (distinguishedNames.size() > 1) {
            msg = "Multiple entries found in LDAP for "+primaryKeyAttr+"=" + uid;
            Z.log.writeToLog(Z.log.ERROR, msg);
            Z.log.writeToLog(Z.log.ERROR, 
               "distinguishedNames found: " + distinguishedNames);
        }

        // Either throw exception or return unique identifier
        if (msg != null)
            throw new Exception(msg);

        return (String) distinguishedNames.get(0);
    }