Code Search for Developers
 
 
  

AuthenticationUtil.java from DSpace at Krugle


Show AuthenticationUtil.java syntax highlighted

/*
 * Authenticate.java
 *
 * Version: $Revision: 1.3 $
 *
 * Date: $Date: 2006/07/05 21:39:29 $
 *
 * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
 * Institute of Technology.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the Hewlett-Packard Company nor the name of the
 * Massachusetts Institute of Technology nor the names of their
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */
package org.dspace.app.xmlui.utils;

import java.sql.SQLException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.cocoon.environment.http.HttpEnvironment;
import org.apache.log4j.Logger;
import org.dspace.authenticate.AuthenticationManager;
import org.dspace.authenticate.AuthenticationMethod;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;

/**
 * Methods for authenticating the user. This is DSpace platform code, as opposed
 * to the site-specific authentication code, that resides in implementations of
 * the org.dspace.eperson.AuthenticationMethod interface.
 * 
 * @author Scott Phillips
 * @author Robert Tansley
 */

public class AuthenticationUtil
{
    private static final Logger log = Logger.getLogger(AuthenticationUtil.class);

    /**
     * Session attribute name for storing the return url where the user should
     * be redirected too once successfully authenticated.
     */
    public static final String REQUEST_INTERRUPTED = "dspace.request.interrupted";
    public static final String REQUEST_RESUME = "dspace.request.resume";
    
    /**
     * These store a message giving a reason for why the request is being interrupted.
     */
    public static final String REQUEST_INTERRUPTED_HEADER = "dspace.request.interrupted.header";
    public static final String REQUEST_INTERRUPTED_MESSAGE = "dspace.request.interrupted.message";
    public static final String REQUEST_INTERRUPTED_CHARACTERS = "dspace.request.interrupted.characters";

    
    /**
     * Session attribute names to store the current user & id.
     */
    private static final String CURRENT_USER = "dspace.current.user";

    private static final String CURRENT_USER_ID = "dspace.current.user.id";
    
    private static final String CURRENT_USER_ADDRESS = "dspace.current.user.address";

    /**
     * Authenticate the current DSpace content based upon given authentication
     * credentials. The AuthenticationManager will consult the configured
     * authentication stack to determine the best method.
     * 
     * @param objectModel
     *            Cocoon's object model.
     * @param email
     *            The email credentials provided by the user.
     * @param password
     *            The password credentials provided by the user.
     * @param realm
     *            The realm credentials proveded by the user.
     * @return Return a current context with either the eperson attached if the
     *         authentication was successfull or or no eperson attached if the
     *         attempt failed.
     */
    public static Context Authenticate(Map objectModel, String email, String password, String realm) 
    throws SQLException
    {
        // Get the real HttpRequest
        HttpServletRequest request = (HttpServletRequest) objectModel
                .get(HttpEnvironment.HTTP_REQUEST_OBJECT);
        Context context = ContextUtil.obtainContext(objectModel);

        int implicitStatus = AuthenticationManager.authenticateImplicit(
                context, null, null, null, request);

        if (implicitStatus == AuthenticationMethod.SUCCESS)
        {
            log.info(LogManager.getHeader(context, "login", "type=implicit"));
            AuthenticationUtil.loggedIn(context, request, context.getCurrentUser());
        }
        else
        {
            // If implicit authentication failed, fall over to explicit.

            int explicitStatus = AuthenticationManager.authenticate(context,
                    email, password, realm, request);

            if (explicitStatus == AuthenticationMethod.SUCCESS)
            {
                // Logged in OK.
                log.info(LogManager
                        .getHeader(context, "login", "type=explicit"));
                AuthenticationUtil.loggedIn(context, request, context
                        .getCurrentUser());
            }
            else
            {
                log.info(LogManager.getHeader(context, "failed_login", "email="
                        + email + ", realm=" + realm + ", result="
                        + explicitStatus));
            }
        }

        return context;
    }

    /**
     * Preform implicite authentication. The authenticationManager will consult
     * the authentication stack for any methods that can implicitly authenticate
     * this session. If the attempt was successfull then the returned context
     * will have an eperson attached other wise the context will not have an
     * eperson attached.
     * 
     * @param objectModel
     *            Cocoon's object model.
     * @return This requests DSpace context.
     */
    public static Context AuthenticateImplicit(Map objectModel)
            throws SQLException
    {
        // Get the real HttpRequest
        final HttpServletRequest request = (HttpServletRequest) objectModel
                .get(HttpEnvironment.HTTP_REQUEST_OBJECT);
        Context context = ContextUtil.obtainContext(objectModel);

        int implicitStatus = AuthenticationManager.authenticateImplicit(
                context, null, null, null, request);

        if (implicitStatus == AuthenticationMethod.SUCCESS)
        {
            log.info(LogManager.getHeader(context, "login", "type=implicit"));
            AuthenticationUtil.loggedIn(context, request, context.getCurrentUser());
        }

        return context;
    }

    /**
     * Store information about the current user in the request and context
     * 
     * @param context
     *            DSpace context
     * @param request
     *            HTTP request
     * @param eperson
     *            the eperson logged in
     */
    public static void loggedIn(Context context, HttpServletRequest request,
            EPerson eperson) throws SQLException
    {
        if (eperson == null)
            return;
        
        HttpSession session = request.getSession();

        context.setCurrentUser(eperson);

        // Set any special groups - invoke the authentication mgr.
        int[] groupIDs = AuthenticationManager.getSpecialGroups(context,
                request);

        for (int groupID : groupIDs)
            context.setSpecialGroup(groupID);

        // We store the current user in the request as an EPerson object...
        request.setAttribute(CURRENT_USER, eperson);

        // and in the session as an ID
        session.setAttribute(CURRENT_USER_ID, eperson.getID());
        
        // and the remote IP address to compare against later requests
        // so we can detect session hijacking.
        session.setAttribute(CURRENT_USER_ADDRESS,
                             request.getRemoteAddr());
    }
    
    public static void loggedIn(Map objectModel, EPerson eperson) throws SQLException
    {
        final HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
        Context context = ContextUtil.obtainContext(objectModel);
        
        loggedIn(context,request,eperson);
    }

    /**
     * Resume any previous login.
     * 
     * @param context
     *            DSpace context
     * @param request
     *            HTTP Request
     */
    public static void resumeLogin(Context context, HttpServletRequest request)
            throws SQLException
    {
        HttpSession session = request.getSession(false);

        if (session != null)
        {
            Integer id = (Integer) session.getAttribute(CURRENT_USER_ID);

            if (id != null)
            {
                String address = (String)session.getAttribute(CURRENT_USER_ADDRESS);
                if (address != null && address.equals(request.getRemoteAddr()))
                {
                    EPerson eperson = EPerson.find(context, id);
                    loggedIn(context, request, eperson);
                }
                else
                {
                    // Possible hack attempt.
                }
            } // if id
        } // if session
    }

    /**
     * Log the user out.
     * 
     * @param context
     *            DSpace context
     * @param request
     *            HTTP request
     */
    public static void loggedOut(Context context, HttpServletRequest request)
    {
        HttpSession session = request.getSession();

        context.setCurrentUser(null);
        request.removeAttribute(CURRENT_USER);
        session.removeAttribute(CURRENT_USER_ID);
        session.removeAttribute(CURRENT_USER_ADDRESS);
    }

    /**
     * Determine if the email can register them selfs or need to be
     * created by a site administrator first.
     * 
     * @param objectModel
     *          The Cocoon object model
     * @param email
     *          The email of the person to be registered.
     * @return true if the email can register, otherwise false.
     */
    public static boolean canSelfRegister(Map objectModel, String email) throws SQLException 
    {
        final HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
        Context context = ContextUtil.obtainContext(objectModel);
        
        return AuthenticationManager.canSelfRegister(context,request,email);
    }
    
    /**
     * Determine if the EPerson (to be created or allready created) has the
     * ability to set their own password.
     * 
     * @param objectModel
     *              The Cocoon object model
     * @param email
     *              The email address of the EPerson.
     * @return
     */
    public static boolean allowSetPassword(Map objectModel, String email) throws SQLException
    {
        final HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
        Context context = ContextUtil.obtainContext(objectModel);
        
        return AuthenticationManager.allowSetPassword(context, request, email);
    }
    
    /**
     * Construct a new, mostly blank, eperson for the given email address. This should
     * only be called once the email address has been verified.
     * 
     * @param objectModel 
     *              The Cocoon object model.
     * @param email
     *              The email address of the new eperson.
     * @return A newly created EPerson object.
     */
    public static EPerson createNewEperson(Map objectModel, String email) throws 
        SQLException, AuthorizeException
    {
        final HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);        
        Context context = ContextUtil.obtainContext(objectModel);
        
        // Need to create new eperson
        // FIXME: TEMPORARILY need to turn off authentication, as usually
        // only site admins can create e-people
        context.setIgnoreAuthorization(true);
        EPerson eperson = EPerson.create(context);
        eperson.setEmail(email);
        eperson.setCanLogIn(true);
        eperson.setSelfRegistered(true);
        eperson.update();
        context.setIgnoreAuthorization(false);
        
        // Give site auth a chance to set/override appropriate fields
        AuthenticationManager.initEPerson(context, request, eperson);
        
        return eperson;   
    }
    
    
    
    
    
    /**
     * Is there a currently interuppted request?
     * 
     * @param objectModel The Cocoon object Model
     */
    public static boolean isInterupptedRequest(Map objectModel) 
    {
    	final HttpServletRequest request = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);        

    	HttpSession session = request.getSession();
    	
    	Object interruptedObject = session.getAttribute(REQUEST_INTERRUPTED);
    	
    	if (interruptedObject instanceof RequestInfo)
    	{
    		// There is currently either an interrupted or yet-to-be resumed request.
    		return true;
    	}
    		
    	// There are not interupted requests.
    	return false;
    }
    
    
    
    /**
     * Interrupt the current request and store if for later resumption. This request will
     * send an http redirect telling the client to authenticate first. Once that has been finished
     * then the request can be resumed.
     * 
     * @param objectModel The Cocoon object Model
     * @param header A message header (i18n tag)
     * @param message A message for why the request was interrupted (i18n tag)
     * @param characters An untranslated messsage, perhaps an error message?
     */
    public static void interruptRequest(Map objectModel, String header, String message, String characters)
    {
    	final HttpServletRequest request = 
    		(HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);        

    	HttpSession session = request.getSession();
        
        // Store this interrupted request untill after the user successfully authenticates.
        RequestInfo interruptedRequest = new RequestInfo(request);
        
        // Set the request as interrupted
        session.setAttribute(REQUEST_INTERRUPTED,interruptedRequest);
        session.setAttribute(REQUEST_RESUME, null); // just to be clear.
        
        // Set the interrupt message
        session.setAttribute(REQUEST_INTERRUPTED_HEADER, header);
        session.setAttribute(REQUEST_INTERRUPTED_MESSAGE, message);
        session.setAttribute(REQUEST_INTERRUPTED_CHARACTERS, characters);
        
        
    }
    
    
    /**
     * Set the interrupted request to a resumable state. The
     * next request that the server recieves (for this session) that
     * has the same servletPath will be replaced with the previously
     * inturrupted request.
     * 
     * @param objectModel The Cocoon object Model
     * @return
     */
    public static String resumeInterruptedRequest(Map objectModel)
    {
    	final HttpServletRequest request = 
    		(HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);        

    	HttpSession session = request.getSession();
        
    	// Clear the interrupt message
	    session.setAttribute(AuthenticationUtil.REQUEST_INTERRUPTED_HEADER, null);
	    session.setAttribute(AuthenticationUtil.REQUEST_INTERRUPTED_MESSAGE, null);
	    session.setAttribute(AuthenticationUtil.REQUEST_INTERRUPTED_CHARACTERS, null);
    	
        // Set the request as interrupted
        Object interruptedObject = session.getAttribute(REQUEST_INTERRUPTED);
        if (interruptedObject instanceof RequestInfo)
        {
        	RequestInfo interruptedRequest = (RequestInfo) interruptedObject;
        	
        	session.setAttribute(REQUEST_INTERRUPTED, null);
        	session.setAttribute(REQUEST_RESUME, interruptedRequest); 
        	
        	// Return the path for which this request belongs too. Only urls
        	// for this path may be resumed.
        	return interruptedRequest.getServletPath();
        }
        
        // No request was interrupted.
        return null;
    }
    
    
    
    /**
     * Check to see if this request should be resumed.
     * 
     * @param realHttpRequest The current real request
     * @return Either the current real request or a stored request that was previously interrupted.
     */
    public static HttpServletRequest resumeRequest(HttpServletRequest realHttpRequest) 
    {
    	// First check to see if there is a resumed request.
    	HttpSession session = realHttpRequest.getSession();
    	//session.setMaxInactiveInterval(60);
        Object object = session.getAttribute(REQUEST_RESUME);
    	
        // Next check to make sure it's the right type of object, 
        // there should be no condition where it is not - but always 
        // safe to check.
        if (object instanceof RequestInfo)
        {
        	RequestInfo interruptedRequest = (RequestInfo) object;
        
        	// Next, check to make sure this real request if for the same url
        	// path, if so then resume the previous request.
        	String interruptedServletPath = interruptedRequest.getServletPath();
        	String realServletPath = realHttpRequest.getServletPath();
        	
        	if (realServletPath != null && 
        		realServletPath.equals(interruptedServletPath))
        	{
        		// Clear the resumed request and send the request back to be resumed.
        		session.setAttribute(REQUEST_INTERRUPTED, null);
        		session.setAttribute(REQUEST_RESUME, null);
 
        		return interruptedRequest.wrapRequest(realHttpRequest);
        	}
        }
    	// Otherwise return the real request.
    	return realHttpRequest;
    }
    
}




See more files for this project here

DSpace

Open Source Digital Asset Management system that enables services for access, provision, stewardship and re-use of digital assets with a focus on educational and research materials

Project homepage: http://sourceforge.net/projects/dspace
Programming language(s): Java,JSP,XML
License: other

  AuthenticationUtil.java
  ContextUtil.java
  DSpaceValidity.java
  HandleUtil.java
  RequestInfo.java
  RequestUtils.java
  UIException.java