Package com.google.gsa.proxy.auth.session

Source Code of com.google.gsa.proxy.auth.session.CrawlingSession

/**
  * 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.proxy.auth.session;

import com.google.gsa.AuthenticationProcessImpl;
import com.google.gsa.AuthorizationProcessImpl;
import com.google.gsa.Credentials;
import com.google.gsa.proxy.auth.CrawlingUtils;
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 java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

import java.util.Date;
import java.util.Vector;

import javax.servlet.http.Cookie;

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

import org.apache.log4j.Logger;


/**
* This class manages all the session when crawling. It stores a session whenever
* a new crawl request is coming from the appliance and no previous session exists,
* or the existing session has reached the timeout. The session timeout is
* configured in the crawl config file.
* The whole Crawl Proxy security lifecycle resides in this class that implements
* methods used by the other classes in this application when it's needed to set
* ot get something to/from the session.
*
*
*/
public class CrawlingSession {

    //Logger
    private static Logger logger = Logger.getLogger(CrawlingSession.class);

    //Timeout in minutes
    private static long timeout = -1; //default value is -1 (no timeout)

    //Session instance: singleton
    private static Sessions sessions = null;

    //Authentication class name
    private static String authenticationProcessClsName = null;

    //Valve Configuration instance
    private ValveConfiguration valveConf = null;

    //Time
    private static final long MILLS_IN_SEC = 1000;
    private static final long SEC_IN_MIN = 60;

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


    /**
     * Class constructor
     * It creates the session instance if it does not exist
     */
    public CrawlingSession() {
        if (sessions == null) {
            sessions = Sessions.getInstance();
        }
    }

    /**
     * Class constructor
     * It creates the session instance if it does not exist. Sets the timeout
     * that is passed to the method.
     *
     * @param timeout number of minutes the session is going to be active
     */
    public CrawlingSession(long timeout) {
        if (sessions == null) {
            this.timeout = timeout;
            sessions = Sessions.getInstance();
        }
    }

    /**
     * Sets the valve configuration instance (if not already set)
     *
     * @param valveConf unique ValveConfiguration instance
     */
    public void setValveConf(ValveConfiguration valveConf) {
        if (this.valveConf == null) {
            this.valveConf = valveConf;
        }
    }

    /**
     * Creates a new user session and adds it with the other sessions
     *
     * @param sessionID session identifier
     * @param userSession the user session instance to be added
     */
    private void createSession(String sessionID, UserSession userSession) {
        if (sessions != null) {
            sessions.addSession(sessionID, userSession);
        }
    }

    /**
     * Removes an existing session from the session vector
     *
     * @param sessionID session identifier
     */
    private void deleteSession(String sessionID) {
        if (sessions != null) {
            sessions.deleteSession(sessionID);
        }
    }

    /**
     * Returns a session (if it already exists)
     *
     * @param sessionID session identifier
     *
     * @return the user session
     */
    public UserSession getSession(String sessionID) {

        UserSession userSession = null;

        if (sessions != null) {

            userSession = sessions.getUserSession(sessionID);

            if (userSession == null) {
                logger.debug("User session was not found");
            } else {
                logger.debug("User session found");
            }
        } else {
            logger.debug("Sessions vector is null");
        }
        return userSession;
    }

    /**
     * Checks if a user session already exists
     *
     * @param sessionID session identifier
     *
     * @return if the user session exists or not
     */
    public boolean doesSessionExist(String sessionID) {

        boolean sessionExist = false;

        if (sessions != null) {
            sessionExist = sessions.doesSessionExist(sessionID);
        }
        return sessionExist;
    }

    /**
     * It authenticates the user the first time against the root authentication
     * process defined in the configuration files. Manages the sessions as well accordingly.
     * Returns the result of the authentication process as a standard HTTP
     * error code
     *
     * @param sessionID sesion identifier
     * @param userName user login
     * @param request HTTP request coming from the GSA
     * @param response HTTP response that is going to be sent back to the GSA
     * @param authCookies cookies created during the authentication process
     * @param url url requested
     * @param creds crawler credentials
     * @param id credential id that is going to be used as the main authn credentials
     *
     * @return the HTTP error code as a result of the authentication process
     */
    public int authenticate(String sessionID, String userName,
                            HttpServletRequest request,
                            HttpServletResponse response,
                            Vector<Cookie> authCookies, String url,
                            Credentials creds, String id) {

        int authnResponse = HttpServletResponse.SC_UNAUTHORIZED;

        logger.debug("Authenticate method");

        //Use a Valve internal URL
        String internalURL = valveConf.getTestFormsCrawlUrl();
        if ((internalURL == null) || (internalURL.equals(""))) {
            internalURL = url;
        }

        //only allow once process in the authenticate method
        synchronized (sessions) {

            try {
                //protection: just in case more than one thread enters in this method
                if (doesSessionExist(sessionID)) {
                    logger.debug("The session is now OK. Returning with SC_OK");
                    return HttpServletResponse.SC_OK;
                }
                //authentication
                logger.debug("Authenticate crawler");

                //Authentication process
                AuthenticationProcessImpl authenticationProcessCls;
                try {
                    authenticationProcessCls = setAuthenticationProcessImpl();
                } catch (ValveConfigurationException e) {
                    logger.error("Valve configuration error: " +
                                 e.getMessage(), e);
                    authnResponse =
                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                    return authnResponse;
                }

                if (authenticationProcessCls != null) {
                    authnResponse =
                            authenticationProcessCls.authenticate(request,
                                                                  response,
                                                                  authCookies,
                                                                  internalURL,
                                                                  creds, id);
                }

                if (authnResponse == HttpServletResponse.SC_OK) {
                    //create session
                    logger.debug("Authentication process has been OK. Let's create the session");
                    long sessionCreationTime = System.currentTimeMillis();
                    //Create authn cookie
                    Cookie authnCookie = createAuthNCookie(sessionID);
                    //add authn cookie into the cookie vector
                    if (authnCookie != null) {
                        CrawlingUtils.addCookie(authCookies, authnCookie);
                    }
                    //Prepare cookies to be included in the session
                    Cookie[] cookies =
                        CrawlingUtils.transformCookiesToArray(authCookies);
                    UserSession userSession =
                        createUserSession(userName, sessionCreationTime, creds,
                                          cookies);
                    createSession(sessionID, userSession);
                    logger.debug("Session created");
                }

            } catch (Exception e) {
                logger.error("Crawl Authentication error: " + e);
            }
        }

        return authnResponse;

    }


    /**
     * It's equivalent to authenticate() method. It authenticates the
     * crawler user once an already existing session is in place although
     * it's no longer valid.
     *
     * @param sessionID sesion identifier
     * @param userName user login
     * @param request HTTP request coming from the GSA
     * @param response HTTP response that is going to be sent back to the GSA
     * @param authCookies cookies created during the authentication process
     * @param url url requested
     * @param creds crawler credentials
     * @param id credential id that is going to be used as the main authn credentials
     *
     * @return the HTTP error code as a result of the authentication process
     */
    public int reauthenticate(String sessionID, String userName,
                              HttpServletRequest request,
                              HttpServletResponse response,
                              Vector<Cookie> authCookies, String url,
                              Credentials creds, String id) {

        int authnResponse = HttpServletResponse.SC_UNAUTHORIZED;

        logger.debug("Reauthenticate method");

        //Use a Valve internal URL
        String internalURL = valveConf.getTestFormsCrawlUrl();
        if ((internalURL == null) || (internalURL.equals(""))) {
            internalURL = url;
        }

        //only allow once process in the authenticate method
        synchronized (sessions) {

            try {
                //protection: just in case more than one thread enters in this method                
                if (isValidSession(sessionID)) {
                    logger.debug("The session is now OK. Returning with SC_OK");
                    return HttpServletResponse.SC_OK;
                }

                //delete session                
                if (doesSessionExist(sessionID)) {
                    logger.debug("Deleting invalid session");
                    deleteSession(sessionID);
                }

                //reauthentication
                logger.debug("Reauthenticate crawler");

                //Authentication process
                AuthenticationProcessImpl authenticationProcessCls;
                try {
                    authenticationProcessCls = setAuthenticationProcessImpl();
                } catch (ValveConfigurationException e) {
                    logger.error("Valve configuration error: " +
                                 e.getMessage(), e);
                    authnResponse =
                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
                    return authnResponse;
                }

                if (authenticationProcessCls != null) {
                    authnResponse =
                            authenticationProcessCls.authenticate(request,
                                                                  response,
                                                                  authCookies,
                                                                  internalURL,
                                                                  creds, id);
                }

                if (authnResponse == HttpServletResponse.SC_OK) {
                    logger.debug("Authentication process has been OK. Let's create the session");
                    long sessionCreationTime = System.currentTimeMillis();
                    //Create authn cookie
                    Cookie authnCookie = createAuthNCookie(sessionID);
                    //add authn cookie into the cookie vector
                    if (authnCookie != null) {
                        CrawlingUtils.addCookie(authCookies, authnCookie);
                    }
                    //Prepare cookies to be included in the session
                    Cookie[] cookies =
                        CrawlingUtils.transformCookiesToArray(authCookies);
                    //Create session
                    UserSession userSession =
                        createUserSession(userName, sessionCreationTime, creds,
                                          cookies);
                    createSession(sessionID, userSession);
                    logger.debug("Session created");
                }

            } catch (Exception e) {
                logger.error("Crawl Authentication error: " + e);
            }
        }

        return authnResponse;

    }

    /**
     * It creates the authentication cookie created as a result of a
     * succesful authentication process.
     *
     * @param sessionID the session identifier
     *
     * @return the authentication cookie
     */
    private Cookie createAuthNCookie(String sessionID) {

        Cookie authCookie = null;

        //Encoding sessionID
        String encodedSessionID = null;
        try {
            encodedSessionID = URLEncoder.encode(sessionID, encoder);
        } catch (UnsupportedEncodingException e) {
            logger.error("Error during session encoding: " + e.getMessage(),
                         e);
            encodedSessionID = sessionID;
        }

        //read parameters from config file
        String authCookieName = null;
        String authCookieDomain = null;
        String authCookiePath = null;
        int authMaxAge = -1;
        try {
            authCookieName = valveConf.getAuthCookieName();
            authCookieDomain = valveConf.getAuthCookieDomain();
            authCookiePath = valveConf.getAuthCookiePath();
            authMaxAge = new Integer(valveConf.getAuthMaxAge()).intValue();
        } catch (Exception e) {
            logger.error("Error when reading cookie parameters. Check auth* params in Valve config file");
            return null;
        }

        authCookie = new Cookie(authCookieName, encodedSessionID);

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

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

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

        return authCookie;
    }


    /**
     * Checks if the session is still valid
     *
     * @param sessionID session identifier
     *
     * @return if the session is still valid or not
     */
    public boolean isValidSession(String sessionID) {

        boolean validSession = false;
        UserSession userSession = null;

        try {

            if (sessions != null) {
                userSession = sessions.getInstance().getUserSession(sessionID);
                if (userSession != null) {
                    logger.debug("User Session exists");
                    if (userSession.getValidSession()) {
                        if (timeout < 0) {
                            //if timeout is less than 0, the session is valid
                            validSession = true;
                        } else {
                            //check if it's still a valid session
                            validSession = sessionValidity(userSession);
                            logger.debug("Checking session validity: " +
                                         validSession);
                        }
                    }
                } else {
                    logger.debug("User Session does NOT exist");
                }
            }

        } catch (Exception e) {
            logger.error("Error during session validation: " + e);
        }

        return validSession;

    }

    /**
     * Checks if the entire user session that it's passed to this method
     * is still valid based on the creation time and the session timeout
     *
     * @param userSession user session to be checked
     *
     * @return if the session is still valid or not
     */
    private boolean sessionValidity(UserSession userSession) {

        boolean sessionValidity = false;

        try {

            if (userSession != null) {
                long creationTime = userSession.getSessionCreationTime();
                long currentTime = System.currentTimeMillis();
                long timeoutMills = timeout * SEC_IN_MIN * MILLS_IN_SEC;
                long validityTime = creationTime + timeoutMills;
                if (validityTime >= currentTime) {
                    sessionValidity = true;
                }

            } else {
                logger.debug("User Session is null");
            }

        } catch (Exception e) {
            logger.error("Error when checking if session is valid based on timeout: " +
                         e);
        }

        return sessionValidity;

    }

    /**
     * Creates a new user session instance with the information passed
     *
     * @param userName user login
     * @param sessionCreationTime long var that holds the session creation time
     * @param userCredentials user credential container
     * @param cookies authentication cookies created during the login process
     *
     * @return the user session created for this method
     */
    public UserSession createUserSession(String userName,
                                         long sessionCreationTime,
                                         Credentials userCredentials,
                                         Cookie[] cookies) {

        UserSession userSession = null;

        try {
            userSession =
                    new UserSession(userName, sessionCreationTime, userCredentials,
                                    cookies);
        } catch (Exception ex) {
            logger.error("Error during the instatiation of the User Session: " +
                         ex);
        } finally {
        }

        return userSession;
    }

    /**
     * Sets the authentication process that is declared in the configuration
     * files. This class will drive the authentication process and it's usually
     * rootAuthenticationProcess class.
     *
     * @return the authentication process
     *
     * @throws ValveConfigurationException
     */
    public AuthenticationProcessImpl setAuthenticationProcessImpl() throws ValveConfigurationException {

        AuthenticationProcessImpl authenticationProcessImpl = null;

        //Set authenticationProcessClsName if it has not been done yet
        if (authenticationProcessClsName == null) {
            //read the authorization class name from Valve Config
            if (valveConf != null) {
                authenticationProcessClsName =
                        valveConf.getAuthenticationProcessImpl();
                logger.debug("Setting authenticationProcessClsName: " +
                             authenticationProcessClsName);
            } else {
                // Throw Configuration Exception
                throw new ValveConfigurationException("Valve Configuration file has not been set correctly");
            }

        }

        // Protection
        if ((authenticationProcessClsName == null) ||
            (authenticationProcessClsName.equals(""))) {

            // Throw Configuration Exception
            throw new ValveConfigurationException("Configuration parameter [authorizationProcessImpl] has not been set correctly");

        }

        try {

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

        } catch (InstantiationException ie) {

            // Throw Configuration Exception
            throw new ValveConfigurationException("Configuration parameter [authorizationProcessImpl] has not been set correctly - InstantiationException");


        } catch (IllegalAccessException iae) {

            // Throw Configuration Exception
            throw new ValveConfigurationException("Configuration parameter [authorizationProcessImpl] has not been set correctly - IllegalAccessException");

        } catch (ClassNotFoundException cnfe) {

            // Throw Configuration Exception
            throw new ValveConfigurationException("Configuration parameter [authorizationProcessImpl] has not been set correctly - ClassNotFoundException");

        }

        return authenticationProcessImpl;

    }

}
TOP

Related Classes of com.google.gsa.proxy.auth.session.CrawlingSession

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.