Package com.google.gsa

Source Code of com.google.gsa.Authenticate

/**
  * 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;

import java.io.IOException;

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


import com.google.gsa.sessions.SessionTimer;

import com.google.gsa.sessions.Sessions;
import com.google.gsa.sessions.UserIDEncoder;
import com.google.gsa.sessions.UserSession;

import com.google.gsa.valve.configuration.ValveConfiguration;

import com.google.gsa.valve.configuration.ValveConfigurationException;
import com.google.gsa.valve.configuration.ValveConfigurationInstance;
import com.google.gsa.valve.errormgmt.ErrorManagement;

import com.google.gsa.valve.saml.SAMLArtifactProcessor;
import com.google.gsa.valve.saml.authn.SAMLAuthN;
import com.google.gsa.valve.utils.ValveUtils;

import java.net.URLEncoder;

import java.util.Vector;

import org.apache.log4j.Logger;

import javax.security.auth.Subject;


/**
* This is the main authentication servlet when a login form is being used to
* get user credentials. It implements the whole authentication process when
* the username and password is collected up and starts the global authentication
* process for the user.
* <p>
* It invokes the root authentication process to garantee the user is
* authenticated in all the backend repositories. It supports both the SAML
* and the Forms Based interface.
* <p>
* If the overall process result is an unauthorized, a 401 error message is
* sent back to the user's browser.
* <p>
* It also handles crawling when Forms Based authentication has been set.
*
*/
public class Authenticate extends HttpServlet {

    private static final long serialVersionUID = -8944353938289271212L;

    private static Logger logger = null;

    private ValveConfiguration valveConf;

    //Vars for Krb support
    private boolean isKerberos = false;

    //Session Management Var
    private boolean isSessionEnabled = false;
    long maxSessionAge;
    long sessionTimeout;
    long sessionCleanup;
    SessionTimer sessionTimer;

    public static final long SEC_IN_MIN = 60;

    private static final String KRB5_ID = "krb5";
   
    //authn process class name
    String authenticationProcessClsName = null;    

    //Cookie vars           
    String authCookieDomain = null;
    String authCookiePath = null;
    String authCookieName = null;
    int authMaxAge = 300;
    String refererCookieName = null;   

    ErrorManagement errorMngmt = null;

    //Encoding
    static String encoder = "UTF-8";

    //SAML
    boolean isSAML = false;
    String refererSAML = null;
    String relayState = null;
    String samlRequest = null;


    static {

        // Instantiate logger
        logger = Logger.getLogger(Authenticate.class);

    }

    /**
     * Servlet's doPost: processes the POST request coming from the login form
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    public void doPost(HttpServletRequest request,
                       HttpServletResponse response) throws IOException,
                                                            ServletException {

        logger.debug("Authenticate: doPost");

        // Read XML config file pointer               
        String gsaValveConfigPath = null;

        //SAML
        if (request.getAttribute("gsaValveConfigPath") == null) {
            //Get Parameter instead of attribute: SAML
            gsaValveConfigPath =
                    request.getParameter("gsaValveConfigPath").toString();
        } else {
            gsaValveConfigPath =
                    request.getAttribute("gsaValveConfigPath").toString();
        }


        logger.debug("Config file: " + gsaValveConfigPath);

        //Create the credentials store
        try {
            this.valveConf =
                    ValveConfigurationInstance.getValveConfig(gsaValveConfigPath);
        } catch (ValveConfigurationException e) {
            logger.error("Valve Config instantiation error: " + e);
        }

        //credentials               
        Credentials creds = new Credentials();
        String username = null;
       
        //GSA Authn cookie
        Cookie gsaAuthCookie = null;

        //authCookies vector
        Vector<Cookie> authCookies = new Vector<Cookie>();
       
        //AuthN process instance       
        AuthenticationProcessImpl authenticationProcessCls = null;

        logger.debug("Authenticate servlet Start");

        //Read config vars from file
        boolean isConfigOK = setValveParams(request);
        logger.debug("Checking if vars were read properly");
        //protect
        if (!isConfigOK) {
            logger.error("Configuration is not OK. Check your config file but either you are trying to use Kerberos Negotiation (use the Kerberized frontend instead)" +
                         "or Kerberos is active but Session does not (they have to be as well). Please review documentation before proceeding");
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                               "Bad configuration. Contact application administrator");
            return;
        }

        //Session ID vars definition
        String sessionID = null;
        String encodedSessionID = null;

        Cookie cookies[] = null;
        Cookie gsaRefererCookie = null;

        // Retrieve cookies
        cookies = request.getCookies();
        logger.debug(cookies.length + " cookies found before authenticating");
        // Protection
        if (cookies != null) {

            // Look for the referer cookie
            for (int i = 0; i < cookies.length; i++) {
                logger.trace(cookies[i].getName() + ":" +
                             cookies[i].getValue());
                // Look for the referer cookie
                if ((cookies[i].getName()).equals(refererCookieName)) {

                    // Cache cookie
                    gsaRefererCookie = cookies[i];

                    // Exit
                    break;

                }

            }

        }

        // Protection
        if (!isSAML) {
            if (gsaRefererCookie == null) {

                // Raise error
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                   "The GSA authentication servlet couldn't read the referer cookie");

                // Log error
                logger.error("The GSA authentication servlet couldn't read the referer cookie, pls. check the cookie domain value");

                // Return
                return;

            }
        } else {
            //SAML

            //Get SAML Params
            relayState = request.getParameter("RelayState");
            samlRequest = request.getParameter("SAMLRequest");
            boolean noParams = false;

            //Protection
            if ((relayState == null) || (relayState.equals(""))) {
                noParams = true;
            } else {
                if ((samlRequest == null) || (samlRequest.equals(""))) {
                    noParams = true;
                }
            }

            if (noParams) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                                   "Invalid request");
                return;
            }

        }

        //Setting root credentials coming from the login form
        username = settingRootCredentials(creds, request);
        logger.debug("Username is: " + username);

        // Instantiate the authentication process class
        try {

            // Instantiate the authorization process class
            authenticationProcessCls =
                    (AuthenticationProcessImpl)Class.forName(authenticationProcessClsName).newInstance();

            authenticationProcessCls.setValveConfiguration(valveConf);


        } catch (InstantiationException e) {

            // Log error
            logger.error("InstantiationException - Authentication servlet parameter [authenticationProcessImpl] has not been set correctly");

            // Return
            return;

        } catch (IllegalAccessException e) {

            // Log error
            logger.error("IllegalAccessException - Authentication servlet parameter [authenticationProcessImpl] has not been set correctly");

            // Return
            return;

        } catch (ClassNotFoundException e) {

            // Log error
            logger.error("ClassNotFoundException - Authentication servlet parameter [authenticationProcessImpl] has not been set correctly");
            logger.error("Cannot find class: " + authenticationProcessClsName);

            // Return
            return;

        }

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

        //creation time var
        long creationTime = System.currentTimeMillis();

        //Instantiate authentication cookie with creation time
        //SET a value for the USERID
        sessionID = UserIDEncoder.getID(username, creationTime);
        encodedSessionID = URLEncoder.encode(sessionID, encoder);
        gsaAuthCookie = new Cookie(authCookieName, encodedSessionID);

        // Set cookie domain
        gsaAuthCookie.setDomain(authCookieDomain);

        // Set cookie path
        gsaAuthCookie.setPath(authCookiePath);

        // Set expiration time
        gsaAuthCookie.setMaxAge(authMaxAge);

        try {

            // Execute the authentication process in here
            if (!isSAML) {
                statusCode =
                        authenticationProcessCls.authenticate(request, response,
                                                              authCookies,
                                                              gsaRefererCookie.getValue(),
                                                              creds, null);
            } else {
                statusCode =
                        authenticationProcessCls.authenticate(request, response,
                                                              authCookies,
                                                              valveConf.getTestFormsCrawlUrl(),
                                                              creds, null);
            }

        } catch (Exception e) {

            // Debug
            logger.error("Authentication process raised exception: " +
                         e.getMessage(), e);

        }

        // Protection
        if (statusCode != HttpServletResponse.SC_OK) {

            //Send personalized error message (if any)
            try {
                //create the instance if it does not exist
                if (errorMngmt == null) {
                    errorMngmt =
                            new ErrorManagement(valveConf.getErrorLocation());
                }

                //protection
                if (errorMngmt != null) {
                    errorMngmt.showHTMLError(response,
                                             errorMngmt.processError(statusCode));
                }

            } catch (ValveConfigurationException e) {
                logger.error("Configuration error: " + e);
            }

            // Raise error
            response.setStatus(statusCode);

            // Debug
            if (logger.isDebugEnabled())
                logger.debug("Authentication process failed");

            // Return
            return;

        }

        //Session support
        if (isSessionEnabled) {

            logger.error("Session is enabled");
            UserSession userSession = new UserSession();
            userSession.setUserName(username);
            userSession.setSessionCreationTime(creationTime);
            userSession.setSessionLastAccessTime(creationTime);

            //Manage Cookies
            //add Auth Cookie to the authCookies vector
            authCookies.add(gsaAuthCookie);
            //add cookies to session
            userSession.setCookies(setCookieArray(authCookies));
            //add creds                   
            userSession.setUserCredentials(creds);

            if (isKerberos) {

                //get credentials
                boolean nonValidCred = getKrbCredentials(creds, userSession);

                if (nonValidCred) {
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                                       "Credentials not valid");

                    // Log error
                    logger.error("Kerberos Subject has not been created properly");

                    // Return
                    return;
                }

            }

            //Store Session in the Session Map
            Sessions sessions = Sessions.getInstance();
            //Setting session times
            sessions.setMaxSessionAgeMinutes(maxSessionAge);
            sessions.setSessionTimeoutMinutes(sessionTimeout);
            sessions.addSession(sessionID, userSession);

            logger.debug("User Session created");
        }

        // Add internal authentication cookie
        response.addCookie(gsaAuthCookie);

        // Debug
        if (logger.isDebugEnabled())
            logger.debug("Authentication process successful");

        if (!isSAML) {

            // Debug
            if (logger.isDebugEnabled())
                logger.debug("Redirecting user to: " +
                             gsaRefererCookie.getValue());

            // Redirect
            response.sendRedirect(gsaRefererCookie.getValue());

        } else {
            //create the artifact
            long maxArtifactAge =
                new Long(valveConf.getSAMLConfig().getMaxArtifactAge()).longValue();
            //Instead of using the username, we'll use the session id
            String artifact =
                SAMLArtifactProcessor.getInstance(maxArtifactAge).storeArtifact(sessionID);

            //Create the referer var

            //redirect to the GSA's Artifact consumer
            try {
                refererSAML =
                    ValveUtils.getGSAHost("", valveConf, cookies, valveConf.getRefererCookieName());           
                SAMLAuthN samlAuthN = new SAMLAuthN();
                String redirectURL =
                    samlAuthN.redirectLocation(refererSAML, relayState, artifact);
                logger.debug("SAML:Redirecting to " + redirectURL);
                response.sendRedirect(redirectURL);
            } catch (ValveConfigurationException e) {
                logger.error ("Configuration error: "+ e.getMessage(),e);
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        }

    }

    /**
     * Servlet's doGet: processes a GET request (only valid for kerberos
     * requests)
     *
     * @param request HTTP request
     * @param response HTTP response
     *
     * @throws IOException
     * @throws ServletException
     */
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws IOException,
                                                           ServletException {

        //Add support for Kerberos   
        if ((request.getAttribute("isKerberos")).toString().equals("true")) {

            doPost(request, response);

        } else {

            // Raise error
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                               "The GSA Authenticate servlet does not accept GET requests!");
        }

    }

    /**
     * Transforms a Cookie vector into a cookie array
     *
     * @param authCookies cookie vector
     *
     * @return cookie array
     */
    public Cookie[] setCookieArray(Vector<Cookie> authCookies) {
        Cookie[] arrayCookie = null;
        if (!authCookies.isEmpty()) {
            logger.debug("Cookie array is not null. Contains " +
                         authCookies.size() + " entries");
            arrayCookie = new Cookie[authCookies.size()];
            for (int i = 0; i < authCookies.size(); i++) {
                logger.debug("Cookie [" + i + "]: " +
                             authCookies.elementAt(i).getName() + ":" +
                             authCookies.elementAt(i).getValue());
                arrayCookie[i] = authCookies.elementAt(i);
            }
        }
        return arrayCookie;
    }

    /**
     * Gets Kerberos credentials from the user session
     *
     * @param creds credentials
     * @param userSession user session
     *
     * @return boolean - if Krb credentials exists
     */
    public boolean getKrbCredentials(Credentials creds,
                                     UserSession userSession) {
        boolean nonValidCred = true;
        try {
            if (creds.getCredential(KRB5_ID) != null) {
                Subject krbSubject = creds.getCredential(KRB5_ID).getSubject();
                if (krbSubject != null) {
                    logger.error("Kerberos Subject exists");

                    userSession.setKerberosCredentials(krbSubject);

                    nonValidCred = false;
                }

            }
        } catch (Exception e) {
            logger.error("Error getting Krb credentials: " + e.getMessage(),
                         e);
            nonValidCred = true;
        }
        return nonValidCred;
    }

    /**
     * Sets the Valve configuration parameters
     *
     * @param request HTTP request
     *
     * @return boolean - if config is OK
     */
    public boolean setValveParams(HttpServletRequest request) {

        boolean isConfigOK = true;
        // Read HTTP request attributes
        logger.debug("Reading configuration vars");
        try {

            authCookieName = valveConf.getAuthCookieName();
            logger.debug("authCookieName: " + authCookieName);
            //refererCookieName = (request.getAttribute("refererCookie")).toString();
            refererCookieName = valveConf.getRefererCookieName();
            logger.debug("refererCookieName: " + refererCookieName);

            authCookieDomain = valveConf.getAuthCookieDomain();
            authCookiePath = valveConf.getAuthCookiePath();
            try {
                authMaxAge = Integer.parseInt(valveConf.getAuthMaxAge());
            } catch (NumberFormatException nfe) {
                logger.error ("Invalid authMaxAge value in the config: "
                              + nfe.getMessage());
                logger.error ("Setting authMaxAge to -1...");
                authMaxAge = -1;
            }
            authenticationProcessClsName =
                    valveConf.getAuthenticationProcessImpl();

            //Is it SAML
            if (valveConf.getSAMLConfig().isSAML().equals("true")) {
                isSAML = true;
            }

            //Is it Kerberos?
            if (valveConf.getKrbConfig().isKerberos().equals("true")) {
                isKerberos = true;
                maxSessionAge =
                        (new Long(valveConf.getSessionConfig().getMaxSessionAge())).longValue();
                //Is it Negotiate?
                if (valveConf.getKrbConfig().isNegotiate().equals("true")) {
                    //Negotiation can not be used. Use Kerberos frontend instead
                    isConfigOK = false;
                } else {
                    if (valveConf.getSessionConfig().isSessionEnabled().equals("false")) {
                        //Session has to be enabled if Kerberos is used
                        isConfigOK = false;
                    }
                }
            } else {
                isKerberos = false;
            }

            //Set Session Vars
            if (valveConf.getSessionConfig().isSessionEnabled().equals("true")) {
                isSessionEnabled = true;
                //Set Kerberos and Session vars
                maxSessionAge =
                        (new Long(valveConf.getSessionConfig().getMaxSessionAge())).longValue();
                sessionTimeout =
                        (new Long(valveConf.getSessionConfig().getSessionTimeout())).longValue();
                sessionCleanup =
                        (new Long(valveConf.getSessionConfig().getSessionCleanup())).longValue();
            } else {
                isSessionEnabled = false;
            }

            //if ((isSessionEnabled)||(isKerberos)) {
            if (isSessionEnabled) {
                logger.debug("Getting sessionTimer instance");
                sessionTimer =
                        SessionTimer.getInstance(isSessionEnabled, isKerberos,
                                                 sessionCleanup);
                sessionTimer.setTimer();
            }
        } catch (NullPointerException e) {
            logger.error("Null pointer exception when setting config vars: " +
                         e.getMessage(), e);
            isConfigOK = false;
        } catch (Exception e) {
            logger.error("Exception when setting config vars: " +
                         e.getMessage(), e);
            isConfigOK = false;
        }

        return isConfigOK;
    }

    /**
     * Setting root credentials that are coming in the HTTP request
     *
     * @param creds credentials
     * @param request HTTP request
     *
     * @return username
     */
    public String settingRootCredentials(Credentials creds,
                                         HttpServletRequest request) {

        String username = null;
        try {
            // Read HTTP request parameters
            username = request.getParameter("UserID");
            logger.debug("Adding credentials for root to credentials store");
            Credential rootCred = new Credential("root");
            rootCred.setUsername(username);
            rootCred.setPassword(request.getParameter("Password"));
            creds.add(rootCred);
        } catch (Exception e) {
            logger.error("Error when getting credentials from parameters");
        }

        return username;

    }

}
TOP

Related Classes of com.google.gsa.Authenticate

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.