org.dspace.webmvc.utils.Authenticate.java Source code

Java tutorial

Introduction

Here is the source code for org.dspace.webmvc.utils.Authenticate.java

Source

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * http://www.dspace.org/license/
 */
package org.dspace.webmvc.utils;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Locale;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//import javax.servlet.jsp.jstl.core.Config;
import org.apache.log4j.Logger;
import org.dspace.authenticate.AuthenticationManager;
import org.dspace.authenticate.AuthenticationMethod;
import org.dspace.authorize.AuthorizeManager;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.core.ConfigurationManager;
import org.dspace.eperson.EPerson;
import org.dspace.core.I18nUtil;
import org.apache.commons.lang.StringUtils;

/**
 * Methods for authenticating the user. This is DSpace platform code, as opposed
 * to the site-specific authentication code, that resides in implementations of
 * the <code>org.dspace.eperson.AuthenticationMethod</code> interface.
 * 
 * @author Robert Tansley
 * @version $Revision: 5845 $
 */
public class Authenticate {

    /** log4j category */
    private static Logger log = Logger.getLogger(Authenticate.class);

    /**
     * Return the request that the system should be dealing with, given the
     * request that the browse just sent. If the incoming request is from a
     * redirect resulting from successful authentication, a request object
     * corresponding to the original request that prompted authentication is
     * returned. Otherwise, the request passed in is returned.
     * 
     * @param request
     *            the incoming HTTP request
     * @return the HTTP request the DSpace system should deal with
     */
    public static HttpServletRequest getRealRequest(HttpServletRequest request) {
        HttpSession session = request.getSession();

        if (session.getAttribute("resuming.request") != null) {
            // Get info about the interrupted request
            RequestInfo requestInfo = (RequestInfo) session.getAttribute("interrupted.request.info");

            HttpServletRequest actualRequest;

            if (requestInfo == null) {
                // Can't find the wrapped request information.
                // FIXME: Proceed with current request - correct?
                actualRequest = request;
            } else {
                /*
                 * Wrap the current request to make it look like the interruped
                 * one
                 */
                actualRequest = requestInfo.wrapRequest(request);
            }

            // Remove the info from the session so it isn't resumed twice
            session.removeAttribute("resuming.request");
            session.removeAttribute("interrupted.request.info");
            session.removeAttribute("interrupted.request.url");

            // Return the wrapped request
            return actualRequest;
        } else {
            return request;
        }
    }

    /**
     * Resume a previously interrupted request. This is invoked when a user has
     * been successfully authenticated. The request which led to authentication
     * will be resumed.
     * 
     * @param request
     *            <em>current</em> HTTP request
     * @param response
     *            HTTP response
     */
    public static void resumeInterruptedRequest(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        HttpSession session = request.getSession();
        String originalURL = (String) session.getAttribute("interrupted.request.url");

        if (originalURL == null) {
            // If for some reason we don't have the original URL, redirect
            // to My DSpace
            originalURL = request.getContextPath() + "/mydspace";
        } else {
            // Set the flag in the session, so that when the redirect is
            // followed, we'll know to resume the interrupted request
            session.setAttribute("resuming.request", Boolean.TRUE);
        }

        // Send the redirect
        response.sendRedirect(response.encodeRedirectURL(originalURL));
    }

    /**
     * Start the authentication process. This packages up the request that led
     * to authentication being required, and then invokes the site-specific
     * authentication method.
     * 
     * If it returns true, the user was authenticated without any
     * redirection (e.g. by an X.509 certificate or other implicit method) so
     * the process that called this can continue and send its own response.
     * A "false" result means this method has sent its own redirect.
     *
     * @param context
     *            current DSpace context
     * @param request
     *            current HTTP request - the one that prompted authentication
     * @param response
     *            current HTTP response
     *
     * @return true if authentication is already finished (implicit method)
     */
    public static boolean startAuthentication(Context context, HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();

        /*
         * Authenticate:
         * 1. try implicit methods first, since that may work without
         *    a redirect. return true if no redirect needed.
         * 2. if those fail, redirect to enter credentials.
         *    return false.
         */
        if (AuthenticationManager.authenticateImplicit(context, null, null, null,
                request) == AuthenticationMethod.SUCCESS) {
            loggedIn(context, request, context.getCurrentUser());
            log.info(LogManager.getHeader(context, "login", "type=implicit"));
            return true;
        } else {
            // Since we may be doing a redirect, make sure the redirect is not
            // cached
            response.addDateHeader("expires", 1);
            response.addHeader("Pragma", "no-cache");
            response.addHeader("Cache-control", "no-store");

            // Store the data from the request that led to authentication
            RequestInfo info = new RequestInfo(request);
            session.setAttribute("interrupted.request.info", info);

            // Store the URL of the request that led to authentication
            session.setAttribute("interrupted.request.url", getOriginalURL(request));

        } //end else 

        return false;
    }

    public static String redirectLoginPage(Context context, HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        /*
         * Grovel over authentication methods, counting the
         * ones with a "redirect" login page -- if there's only one,
         * go directly there.  If there is a choice, go to JSP chooser.
         */
        Iterator ai = AuthenticationManager.authenticationMethodIterator();
        AuthenticationMethod am;
        int count = 0;
        String url = null;
        while (ai.hasNext()) {
            String s;
            am = (AuthenticationMethod) ai.next();
            s = am.loginPageURL(context, request, response);
            if (s != null) {
                url = s;
                ++count;
            }
        }
        if (count == 1) {
            //response.sendRedirect(url);
            return "redirect:/" + url;
        } else {
            //JSPManager.showJSP(request, response, "/login/chooser.jsp");
            return "/login/chooser";
        }
    }

    /**
     * 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) {
        HttpSession session = request.getSession();

        // For security reasons after login, give the user a new session
        if ((!session.isNew()) && (session.getAttribute("dspace.current.user.id") == null)) {
            // Keep the user's locale setting if set
            Locale sessionLocale = getSessionLocale(request);

            // Get info about the interrupted request, if set
            RequestInfo requestInfo = (RequestInfo) session.getAttribute("interrupted.request.info");

            // Get the original URL of interrupted request, if set
            String requestUrl = (String) session.getAttribute("interrupted.request.url");

            // Invalidate session unless dspace.cfg says not to
            if (ConfigurationManager.getBooleanProperty("webui.session.invalidate", true)) {
                session.invalidate();
            }

            // Give the user a new session
            session = request.getSession();

            // Restore the session locale
            if (sessionLocale != null) {
                //Config.set(request.getSession(), Config.FMT_LOCALE, sessionLocale);
                session.setAttribute("FMT_LOCALE", sessionLocale);
            }

            // Restore interrupted request information and url to new session
            if (requestInfo != null && requestUrl != null) {
                session.setAttribute("interrupted.request.info", requestInfo);
                session.setAttribute("interrupted.request.url", requestUrl);
            }
        }

        context.setCurrentUser(eperson);

        boolean isAdmin = false;

        try {
            isAdmin = AuthorizeManager.isAdmin(context);
        } catch (SQLException se) {
            log.warn("Unable to use AuthorizeManager " + se);
        } finally {
            request.setAttribute("isadmin", Boolean.valueOf(isAdmin));
        }

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

        // and in the session as an ID
        session.setAttribute("dspace.current.user.id", Integer.valueOf(eperson.getID()));

        // and the remote IP address to compare against later requests
        // so we can detect session hijacking.
        session.setAttribute("dspace.current.remote.addr", request.getRemoteAddr());

    }

    /**
     * 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("isadmin");
        request.removeAttribute("dspace.current.user");
        session.removeAttribute("dspace.current.user.id");

        // Keep the user's locale setting if set
        Locale sessionLocale = getSessionLocale(request);

        // Invalidate session unless dspace.cfg says not to
        if (ConfigurationManager.getBooleanProperty("webui.session.invalidate", true)) {
            session.invalidate();
        }

        // Restore the session locale
        if (sessionLocale != null) {
            //Config.set(request.getSession(), Config.FMT_LOCALE, sessionLocale);
            session.setAttribute("FMT_LOCALE", sessionLocale);
        }
    }

    public static String getOriginalURL(HttpServletRequest request) {
        // Make sure there's a URL in the attribute
        storeOriginalURL(request);

        return ((String) request.getAttribute("dspace.original.url"));
    }

    public static void storeOriginalURL(HttpServletRequest request) {
        String orig = (String) request.getAttribute("dspace.original.url");

        if (orig == null) {
            String fullURL = request.getRequestURL().toString();

            if (request.getQueryString() != null) {
                fullURL = fullURL + "?" + request.getQueryString();
            }

            request.setAttribute("dspace.original.url", fullURL);
        }
    }

    public static Locale getSessionLocale(HttpServletRequest request) {
        String paramLocale = request.getParameter("locale");
        Locale sessionLocale = null;
        Locale supportedLocale = null;

        if (!StringUtils.isEmpty(paramLocale)) {
            /* get session locale according to user selection */
            sessionLocale = new Locale(paramLocale);
        }

        if (sessionLocale == null) {
            /* get session locale set by application */
            HttpSession session = request.getSession();
            //sessionLocale = (Locale) Config.get(session, Config.FMT_LOCALE);
            sessionLocale = (Locale) session.getAttribute("FMT_LOCALE");

        }

        /*
         * if session not set by selection or application then default browser
         * locale
         */
        if (sessionLocale == null) {
            sessionLocale = request.getLocale();
        }

        if (sessionLocale == null) {
            sessionLocale = I18nUtil.DEFAULTLOCALE;
        }
        supportedLocale = I18nUtil.getSupportedLocale(sessionLocale);

        return supportedLocale;
    }
}