Package com.google.gsa.valve.modules.ldap

Source Code of com.google.gsa.valve.modules.ldap.LDAPSSO$LDAPAttrRepository

/**
  * Copyright (C) 2008 Google - Enterprise EMEA SE
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
  *
  * http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */

package com.google.gsa.valve.modules.ldap;


import java.io.IOException;

import javax.naming.directory.DirContext;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpException;
import org.apache.log4j.Logger;

import com.google.gsa.AuthenticationProcessImpl;
import com.google.gsa.Credential;
import com.google.gsa.Credentials;
import com.google.gsa.valve.configuration.ValveConfiguration;
import com.google.gsa.valve.configuration.ValveRepositoryConfiguration;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
* The Security Framework is able to manage more than one credential per user.
* This class is able to manage multiple credentials in a LDAP server. This has
* been implemented using some attributes extended in the LDAP that hold the
* credential information for accessing multiple sources. It checks the main
* authentication credentials provided by the user against the LDAP, but once
* the user is authenticated, it populates the multiple credentials to be
* available during the whole security process.
* <p>
* It's able to read multiple username and password attributes from the LDAP
* and populate them in the credential container. It enables the other
* AuthN/AuthZ modules to use them when securely accessing the backend
* systems.
* <p>
* This authentication module uses Java standard LDAP classes that makes
* the integration independent of the directory server.
*
*/
public class LDAPSSO implements AuthenticationProcessImpl {

    //logger
    private Logger logger = null;

    //Valve configuration
    private ValveConfiguration valveConf = null;

    //Hastable and Vector that contains authentication LDAP attributes
    private Vector<String> repositories = new Vector<String>();
    private Map<String, LDAPAttrRepository> ldapAttributes =
        new HashMap<String, LDAPAttrRepository>();

    //LDAP vars parameters
    private String ldapBaseuser = null;
    private String ldapHost = null;
    private String ldapDomain = null;
    private String rdnAttr = null;

    private static final String SSO_COOKIE_NAME = "gsa_ldap_auth";

    //Cookie Max Age
    private int authMaxAge = -1;

    /**
     * Class constructor
     *
     */
    public LDAPSSO() {
        logger = Logger.getLogger(LDAPSSO.class);

    }

    /**
     * Sets the Valve Configuration instance to read the parameters
     * from there
     *
     * @param valveConf the Valve configuration instance
     */
    public void setValveConfiguration(ValveConfiguration valveConf) {
        this.valveConf = valveConf;

    }


    /**
     * This is the main method that does the authentication and should be
     * invoked by the classes that would like to populate new user authentication
     * credentials from the LDAP server.
     * <p>
     * It also authenticates the user against the LDAP server, so that only
     * priviledged users are able to read the LDAP attributes. These multiple
     * credentials are stored in the directory server and populate them in the
     * user's credential container. It enables the other AuthN/AuthZ modules to
     * use them when securely accessing the backend systems.
     * <p>
     * If the LDAP authentication result is OK, it creates an
     * authentication cookie. Anyway, the HTTP response code is returned in this
     * method to inform the caller on the status.
     *
     * @param request HTTP request
     * @param response HTTP response
     * @param authCookies vector that contains the authentication cookies
     * @param url the document url
     * @param creds an array of credentials for all external sources
     * @param id the default credential id to be retrieved from creds
       
     * @return the HTTP error code
       
     * @throws HttpException
     * @throws IOException
     */
    public int authenticate(HttpServletRequest request,
                            HttpServletResponse response,
                            Vector<Cookie> authCookies, String url,
                            Credentials creds, String id) throws HttpException,
                                                                 IOException {

        logger.debug("Start LDAPSSO AuthN process");

        //protection
        repositories.clear();
        ldapAttributes.clear();

        //Insert LDAP attributes from the config file
        getLDAPAttributes(id);

        //First read the u/p the credentails store, in this case using the same as the root login
        logger.debug("LDAPSSO: trying to get creds from repository ID: " + id);
        Credential cred = null;
        try {
            cred = creds.getCredential(id);
        } catch (NullPointerException npe) {
            logger.error("NPE while reading credentials of ID: " + id);
        }
        if (cred == null) {
            cred = creds.getCredential("root");
            if (cred != null) {
                logger.info("LDAPSSO: credential ID used is \"root\"");
            } else {
                logger.error("LDAPSSO: No credentials available for " + id);
            }
        }

        Cookie[] cookies = null;

        // Initialize status code
        int statusCode = HttpServletResponse.SC_UNAUTHORIZED;

        // Read cookies
        cookies = request.getCookies();

        try {
            authMaxAge = Integer.parseInt(valveConf.getAuthMaxAge());
        } catch (NumberFormatException nfe) {
            logger.error("Configuration error: chack the configuration file as the number set for authMaxAge is not OK:");
        }

        //If the required cookie was not found need to authenticate.
        logger.info("Authenticating root user with LDAP");
        try {

            //Check if the LDAP credentials are OK                     
            Ldap ldapconn =
                new Ldap(ldapHost, cred.getUsername(), cred.getPassword(),
                         ldapBaseuser, ldapDomain, rdnAttr);
            try {
                logger.debug("Connecting to LDAP");
                DirContext ctx = ldapconn.openConnection();
                if (ctx == null) {
                    //Just send a comment 
                    logger.debug("The user(" + cred.getUsername() +
                                 ")/password doesn't match");
                    ldapconn.closeConnection(ctx);
                    return (HttpServletResponse.SC_UNAUTHORIZED);
                }


                //Fetching credentials
                logger.debug("Fetching credentials from the LDAP");

                fetchingCredentials(ldapconn, ctx, cred.getUsername(), creds);

                //Close the connection
                ldapconn.closeConnection(ctx);

            } catch (Exception ex) {
                logger.error("LDAP connection problem during user access: " +
                             ex.getMessage(), ex);
                return (HttpServletResponse.SC_UNAUTHORIZED);
            } finally {
            }


            Cookie extAuthCookie = null;

            extAuthCookie = settingCookie();

            //add sendCookies support
            logger.debug("Setting session");
            boolean isSessionEnabled =
                new Boolean(valveConf.getSessionConfig().isSessionEnabled()).booleanValue();
            boolean sendCookies = false;
            if (isSessionEnabled) {
                sendCookies =
                        new Boolean(valveConf.getSessionConfig().getSendCookies()).booleanValue();
            }
            if ((!isSessionEnabled) || ((isSessionEnabled) && (sendCookies))) {
                response.addCookie(extAuthCookie);
            }

            //add cookie to the array
            authCookies.add(extAuthCookie);

            //This would be set to OK or 401 in a real AuthN module
            statusCode = HttpServletResponse.SC_OK;

        } catch (Exception e) {

            // Log error
            logger.error("LDAP SSO authentication failure: " + e.getMessage(),
                         e);


            // Update status code
            statusCode = HttpServletResponse.SC_UNAUTHORIZED;

        }


        // Debug
        logger.debug("Sample Authentication completed (" + statusCode + ")");

        // Return status code
        return statusCode;

    }

    /**
     * Sets the LDAP authentication cookie
     *
     * @return the LDAP authentication cookie
     */
    public Cookie settingCookie() {
        // Instantiate a new cookie
        Cookie extAuthCookie = new Cookie(SSO_COOKIE_NAME, "true");
        String authCookieDomain = null;
        String authCookiePath = null;

        // Cache cookie properties
        authCookieDomain = valveConf.getAuthCookieDomain();
        authCookiePath = valveConf.getAuthCookiePath();

        // Set extra cookie parameters
        extAuthCookie.setDomain(authCookieDomain);
        extAuthCookie.setPath(authCookiePath);
        extAuthCookie.setMaxAge(authMaxAge);

        // Log info
        logger.debug("Adding cookie: " + extAuthCookie.getName() + ":" +
                     extAuthCookie.getValue() + ":" + extAuthCookie.getPath() +
                     ":" + extAuthCookie.getDomain() + ":" +
                     extAuthCookie.getSecure());

        return extAuthCookie;
    }

    /**
     * Gets the LDAP attributes coming from the config file
     *
     * @param id the repository id
     */
    public void getLDAPAttributes(String id) {

        logger.debug("Getting LDAP Attributes");

        ValveRepositoryConfiguration repositoryConfig =
            valveConf.getRepository(id);

        if (repositoryConfig != null) {

            //Reading LDAP vars from configfile    

            logger.debug("Reading LDAP Attributes from config file");

            ldapBaseuser = repositoryConfig.getParameterValue("ldapBaseuser");
            if ((ldapBaseuser != null) && (ldapBaseuser == "")) {
                ldapBaseuser = null;
            }
            ldapHost = repositoryConfig.getParameterValue("ldapHost");
            if ((ldapHost != null) && (ldapHost == "")) {
                ldapHost = null;
            }
            ldapDomain = repositoryConfig.getParameterValue("ldapDomain");
            if ((ldapDomain != null) && (ldapDomain == "")) {
                ldapDomain = null;
            }
            rdnAttr = repositoryConfig.getParameterValue("rdnAttr");
            if ((rdnAttr != null) && (rdnAttr == "")) {
                rdnAttr = null;
            }

            //Getting attributes username and password for all the credentials
            logger.debug("Getting LDAP username and password attributes per each repository");
            boolean attributeExist = true;
            int index = 1;
            while (attributeExist) {
                String idAttr = "id" + index;
                logger.debug("ID is : " + idAttr);
                if (repositoryConfig.getParameterValue(idAttr) != null) {
                    String userNameAttr = "username" + index;
                    String passwordAttr = "password" + index;
                    if ((repositoryConfig.getParameterValue(userNameAttr) !=
                         null) &&
                        (repositoryConfig.getParameterValue(passwordAttr) !=
                         null)) {
                        logger.debug("Adding LDAP attributes for: " +
                                     repositoryConfig.getParameterValue(idAttr));
                        LDAPAttrRepository attrRepository =
                            new LDAPAttrRepository(repositoryConfig.getParameterValue(userNameAttr),
                                                   repositoryConfig.getParameterValue(passwordAttr));
                        ldapAttributes.put(repositoryConfig.getParameterValue(idAttr),
                                           attrRepository);
                        repositories.add(repositoryConfig.getParameterValue(idAttr));
                    } else {
                        logger.error("LDAP attribute username or password for repository number " +
                                     index + " [" +
                                     repositoryConfig.getParameterValue(idAttr) +
                                     "] does NOT exist in the config file. Review configuration");
                    }
                } else {
                    attributeExist = false;
                }
                index++;
            }
        }

    }

    /**
     *
     * For every credentials read at the configuration file it gets the
     * LDAP attributes from the LDAP.
     *
     * @param ldapconn LDAP connection
     * @param ctx LDAP context
     * @param username user id
     * @param creds user credentials
     */
    public void fetchingCredentials(Ldap ldapconn, DirContext ctx,
                                    String username, Credentials creds) {

        for (int i = 0; i < repositories.size(); i++) {
            String id = repositories.elementAt(i);
            logger.debug("ID [" + id + "] found at position #" + i);

            LDAPAttrRepository attrRepository;

            //fetch credentials
            try {
                attrRepository = ldapAttributes.get(id);

                //Get User's DN
                String userDName = ldapconn.getDN(username, ctx);

                logger.info("fetching credentials for (" + id + ")");
                String usernameAttr =
                    ldapconn.getAttributeByDN(attrRepository.getUsernameAttr(),
                                              userDName, ctx);
                String passwordAttr = null;
                if (!usernameAttr.equals(null)) {
                    logger.debug("UserName id[" + id + "]: " + usernameAttr);
                    passwordAttr =
                            ldapconn.getAttributeByDN(attrRepository.getPasswordAttr(),
                                                      userDName, ctx);
                    //add the credentials into the "creds" object
                    logger.debug("LDAP credentials were acquired OK. Adding them into the credential container");
                    Credential credAttr = new Credential(id);
                    credAttr.setUsername(usernameAttr);
                    credAttr.setPassword(passwordAttr);
                    creds.add(credAttr);
                } else {
                    logger.debug("Credentials for " + id +
                                 " were not found for the user " + username);
                }
            } catch (NullPointerException e) {
                logger.warn("NullPointerException when fetching attrs in the LDAP. Probably due to the user does not have those attrs");
            } catch (Exception e) {
                logger.error("Exception fetching LDAP attributes: " +
                             e.getMessage(), e);
            }

        }

    }

    /**
     * Class that implements a pair of username and password LDAP attribute
     * names associated to a one or more repositories (i.e. a user can be
     * authenticated using the value of those attributes in the LDAP against
     * a repository)
     *
     */
    public class LDAPAttrRepository {

        //Username and password pair
        String usernameAttr = null;
        String passwordAttr = null;

        /**
         * Class constructor
         *
         * @param usernameAttr LDAP username attribute
         * @param passwordAttr
         */
        public LDAPAttrRepository(String usernameAttr, String passwordAttr) {
            setUsernameAttr(usernameAttr);
            setPasswordAttr(passwordAttr);
        }

        /**
         * Gets the LDAP username attribute
         *
         * @return LDAP username attribute
         */
        public String getUsernameAttr() {
            return usernameAttr;
        }

        /**
         * Sets the LDAP username attribute
         *
         * @param usernameAttr LDAP username attribute
         */
        public void setUsernameAttr(String usernameAttr) {
            this.usernameAttr = usernameAttr;
        }

        /**
         * Gets the LDAP password attribute
         *
         * @return LDAP password attribute
         */
        public String getPasswordAttr() {
            return passwordAttr;
        }

        /**
         * Sets the LDAP password attribute
         *
         * @param passwordAttr LDAP password attribute
         */
        public void setPasswordAttr(String passwordAttr) {
            this.passwordAttr = passwordAttr;
        }

    }

}
TOP

Related Classes of com.google.gsa.valve.modules.ldap.LDAPSSO$LDAPAttrRepository

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.