Package com.adito.security.actions

Source Code of com.adito.security.actions.ShowLogonAction

package com.adito.security.actions;

import java.util.Calendar;
import java.util.GregorianCalendar;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.Globals;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import com.adito.boot.Util;
import com.adito.core.RedirectWithMessages;
import com.adito.core.UserDatabaseManager;
import com.adito.core.actions.DefaultAction;
import com.adito.realms.Realm;
import com.adito.security.AccountLockedException;
import com.adito.security.AuthenticationModule;
import com.adito.security.AuthenticationScheme;
import com.adito.security.Constants;
import com.adito.security.DefaultAuthenticationScheme;
import com.adito.security.LogonController;
import com.adito.security.LogonControllerFactory;
import com.adito.security.LogonStateAndCache;
import com.adito.security.PasswordAuthenticationModule;
import com.adito.security.SecurityErrorException;
import com.adito.security.SessionInfo;
import com.adito.security.SystemDatabaseFactory;
import com.adito.security.User;
import com.adito.security.UserDatabase;
import com.adito.security.UserNotFoundException;
import com.adito.security.forms.LogonForm;


/**
* Entry point for authentication process. This action maintains the current
* state of the authentication and displays the tiles required for each module.
*/
public class ShowLogonAction extends DefaultAction {

    final static Log log = LogFactory.getLog(ShowLogonAction.class);

    /* (non-Javadoc)
     * @see com.adito.core.actions.DefaultAction#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
                    throws Exception {
        LogonForm logonForm = (LogonForm) form;
       
        /*
         * The logon page should not be shown if already logged on. It is
         * important that hasClientLoggedOn is called first, as this is what
         * places the session lock in the session attributes.
         */
        if (LogonControllerFactory.getInstance().hasClientLoggedOn(request, response) == LogonController.LOGGED_ON
                        && request.getSession().getAttribute(Constants.SESSION_LOCKED) == null) {
            return mapping.findForward("home");
        }

        Util.noCache(response);
       
        // Should we reset the logon process
        boolean reset = request.getParameter("reset") != null;
        // Or do we need to go back to the start
        boolean back = request.getParameter("back") != null;
       
        // Display any messages that should be displayed
        displayMessages(request);
   
      /*
       * All other states process as normal
       */
        ActionForward fwd;
        try {
           
          if(back) {
            /**
             * This is designed to take the user back to the start of their default scheme. This
             * can only be invoked from the authentication scheme selection page.
             */
                LogonStateAndCache logonStateMachine = (LogonStateAndCache) request.getSession().getAttribute(
                        LogonStateAndCache.LOGON_STATE_MACHINE);
                logonStateMachine.setState(LogonStateAndCache.STATE_USERNAME_KNOWN);
                ((LogonForm) form).setUsername(logonStateMachine.getUser() == null ? logonStateMachine.getSpoofedUsername() : logonStateMachine.getUser().getPrincipalName());
                ((LogonForm) form).setHasMoreAuthenticationSchemes(logonStateMachine.enabledSchemesGraeterThanOne());
                return mapping.findForward("display");
          }
         
            // Configure the logon state machine
            LogonStateAndCache logonStateMachine = checkLogonStateMachine(request, response, logonForm, reset);
           
            /*
             * Only when in STARTED state do we collect the username
             */
            if(logonStateMachine.getState() == LogonStateAndCache.STATE_STARTED) {
              logonStateMachine.setState(LogonStateAndCache.STATE_DISPLAY_USERNAME_ENTRY);
              return mapping.findForward("username");
            }
           
            // try to check the auth session, if not you need to sign in again.
            fwd = checkAuthSession((LogonForm)form, reset, mapping, request, response, logonStateMachine);
        } catch (SecurityErrorException see) {
            ActionMessages errs = new ActionMessages();
            errs.add(Globals.ERROR_KEY, see.getBundleActionMessage());
            saveErrors(request, errs);
            request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
            if (form != null)
                form.reset(mapping, request);
            return new RedirectWithMessages(mapping.findForward("refresh"), request);
        } catch (Throwable e) {
            ActionMessages messages = new ActionMessages();
            log.error("Logon not allowed.", e);
            messages.add(Globals.ERROR_KEY, new ActionMessage("login.logonNotAllowed", "Please contact your administrator."));
            saveErrors(request, messages);
            request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
            if (form != null)
                form.reset(mapping, request);
            return new RedirectWithMessages(mapping.findForward("refresh"), request);
        }
        Util.noCache(response);
        return fwd;
    }

    /**
     * Check the state of the authentication session and get the next forward
     * that displays the next authentication module.
     *
     * @param form form
     * @param reset reset authentcation
     * @param mapping mapping
     * @param request request
     * @param response response
     * @param logonStateMachine logon state machine
     * @return forward
     * @throws Exception on any error
     */
    public static ActionForward checkAuthSession(LogonForm form, boolean reset, ActionMapping mapping, HttpServletRequest request,
                    HttpServletResponse response, LogonStateAndCache logonStateMachine) throws Exception{
        AuthenticationScheme authScheme = (AuthenticationScheme) request.getSession().getAttribute(Constants.AUTH_SESSION);
        if (authScheme == null || reset || authScheme.getResourceId() != logonStateMachine.getHighestPriorityScheme().getResourceId()) {

            if (log.isDebugEnabled())
                log.debug("Creating new authentication session using scheme '" + "THE SCHEME NAME" + "'");

            // Try to initalise the highest priority scheme,
            if (request.getSession().getAttribute(Constants.SESSION_LOCKED) != null) {
                // If session locked then only display password

                SessionInfo info = LogonControllerFactory.getInstance().getSessionInfo(request);
                Calendar now = new GregorianCalendar();
                authScheme = new DefaultAuthenticationScheme(info.getRealmId(), Integer.MAX_VALUE, "Fake sheme", "Fake scheme",
                                now, now, true, 0);
                authScheme.addModule(PasswordAuthenticationModule.MODULE_NAME);
            } else {
                authScheme = logonStateMachine.getHighestPriorityScheme();
            }

            if (authScheme == null) {
                log.info("There are no authenticated schemes.");
                return null;
            } else {
               
                authScheme.setUser(logonStateMachine.getUser());
                authScheme.init(request.getSession());
               
                if (authScheme.nextAuthenticationModule() == null) {
                    throw new Exception("No authentication modules have been configured.");
                }
                request.getSession().setAttribute(Constants.AUTH_SESSION, authScheme);
                if (log.isDebugEnabled())
                    log.debug("Scheme " + authScheme.getSchemeName() + " initialised OK");
            }
        }

        while (true) {
            AuthenticationModule module = authScheme.currentAuthenticationModule();
            if (form != null) {
                form.setCurrentModuleIndex(authScheme.getCurrentModuleIndex());
            }

            // The module may wish to forward somewhere other than to the
            // default login page
            ActionForward forward = module.startAuthentication(mapping, request, response);

            if (module.isRequired()) {
                return forward;
            } else {
                // Are we at the end of the sequence
                if (authScheme.nextAuthenticationModule() == null) {
                    return LogonAction.finishAuthentication(authScheme, request, response);
                }
            }
        }
    }
   
    /**
     * Check the logon state machine and configure as necessary.
     *
     * @param request request
     * @param response response
     * @param form form
     * @param reset reset logon
     * @return logon state machine
     * @throws Exception on any error
     */
    LogonStateAndCache checkLogonStateMachine(HttpServletRequest request, HttpServletResponse response, LogonForm form, boolean reset) throws Exception {

        LogonStateAndCache logonStateMachine = (LogonStateAndCache) request.getSession().getAttribute(
                        LogonStateAndCache.LOGON_STATE_MACHINE);

        /** Reset the logon state machine if :-
         *
         * 1. This is the first connection from this browser session.
         * 2. The 'reset' parameter has been passed on the request
         * 3. The logon state machine is in {@link LogonStateAndCache#STATE_RETURN_TO_LOGON}
         *
         */
        UserDatabase udb = UserDatabaseManager.getInstance().getUserDatabase(form.getRealmName());
        if (logonStateMachine == null || logonStateMachine.getState() == LogonStateAndCache.STATE_RETURN_TO_LOGON || reset) {
          /*
           * If the client is already logged on, then we got here because
           * a <i>Session Lock</i> has occured and so only require
           * the users password
           */
            if (LogonControllerFactory.getInstance().hasClientLoggedOn(request, response) == LogonController.LOGGED_ON) {
                logonStateMachine = new LogonStateAndCache(LogonStateAndCache.STATE_DISPLAY_USERNAME_ENTERED, request.getSession());
                logonStateMachine.setUser(LogonControllerFactory.getInstance().getUser(request));
                form.initUser();
                form.setHasMoreAuthenticationSchemes(false);
            } else {
              /*
               * This is a brand new session so we require the username
               */
                logonStateMachine = new LogonStateAndCache(LogonStateAndCache.STATE_STARTED, request.getSession());
                request.getSession().removeAttribute(Constants.AUTH_SESSION);
                if(!Util.isNullOrTrimmedBlank(form.getUsername())) {
                  try {
                    User user = udb.getAccount(form.getUsername());
                    logonStateMachine.removeFromSpoofCache(user.getPrincipalName());
                    form.initUser();
                    try {
                      logonStateMachine.setUser(user);
                    }
                    catch(AccountLockedException ale) {
                      // Continue anyway and get the exception later
                    }
                    logonStateMachine.setState(LogonStateAndCache.STATE_DISPLAY_USERNAME_ENTERED);
                  }
                  catch(UserNotFoundException unfe) {
                      form.initUser();
                      // Spoof some authentication schemes
                      form.setHasMoreAuthenticationSchemes(true);
                  }
                }
               
            }
        } else {
            /*
             * A username has been provided but it was unknown. The error message
             * indicating this will not be displayed until the next stage is
             * complete
             */
          if (logonStateMachine.getState() == LogonStateAndCache.STATE_UNKNOWN_USERNAME) {
              logonStateMachine.setState(LogonStateAndCache.STATE_UNKNOWN_USERNAME_PROMPT_FOR_PASSWORD);
          }
          else  if (logonStateMachine.getState() == LogonStateAndCache.STATE_KNOWN_USERNAME_MULTIPLE_SCHEMES_SELECT){           
            /*
             * The scheme to sign on with has changed, so we need to update the
                 * logon state machine.
                 */
                logonStateMachine.forceHighestPriorityScheme(request.getParameter("selectedAuthenticationScheme"),
                    request.getParameter("username"));
                logonStateMachine.setState(LogonStateAndCache.STATE_KNOWN_USERNAME_MULTIPLE_SCHEMES);               
            } else if (logonStateMachine.getState() == LogonStateAndCache.STATE_KNOWN_USERNAME_NO_SCHEME_SPOOF_PASSWORD_ENTRY){
              /*
                 * The scheme to sign on with has changed, so we need to update the
                 * logon state machine
                 */
                logonStateMachine.setSpoofedHighestPriorityScheme(request.getParameter("username"));
            }
            else if(logonStateMachine.getState() == LogonStateAndCache.STATE_DISPLAY_USERNAME_ENTRY){
              /*
               * The username has been collected, now process it.
               */
              if(Util.isNullOrTrimmedBlank(form.getUsername())) {
                /**
                 * Page refreshed, stay in same state
                 */
                  logonStateMachine.setState(LogonStateAndCache.STATE_STARTED);
              }
              else {
                  logonStateMachine.setState(LogonStateAndCache.STATE_DISPLAY_USERNAME_ENTERED);
                  try {
                    User user = udb.getAccount(form.getUsername());
                    logonStateMachine.removeFromSpoofCache(user.getPrincipalName());
                    try {
                      logonStateMachine.setUser(user);
                    }
                    catch(AccountLockedException ale) {
                      // Continue anyway and get the exception later
                    }
                  }
                  catch(UserNotFoundException unfe) {
                    // Continue anyway
                    String username = request.getParameter("username");
                    Realm realm = UserDatabaseManager.getInstance().getDefaultRealm();
                    logonStateMachine.setState(LogonStateAndCache.STATE_UNKNOWN_USERNAME_PROMPT_FOR_PASSWORD);
                      logonStateMachine.setSpoofedHighestPriorityScheme(username);
                      logonStateMachine.getHighestPriorityScheme().setAccountLock(LogonControllerFactory.getInstance().checkForAccountLock(username, realm.getResourceName()));
                  }
              }
            }
         
            ((LogonForm) form).setHasMoreAuthenticationSchemes(logonStateMachine.enabledSchemesGraeterThanOne());
        }
       
        return logonStateMachine;
    }
   
    void displayMessages(HttpServletRequest request) throws Exception {

        // Check for session lock and display the message
       
        if (request.getSession().getAttribute(Constants.SESSION_LOCKED) != null) {
            ActionMessages messages = new ActionMessages();
            messages.add(Globals.MESSAGE_KEY, new ActionMessage("login.sessionLocked"));
            addMessages(request, messages);
        }
       
        // Check Ip address

        if (!SystemDatabaseFactory.getInstance().verifyIPAddress(request.getRemoteAddr())) {
            ActionMessages errs = new ActionMessages();
            errs.add(Globals.ERROR_KEY, new ActionMessage("login.unauthorizedAddress"));
            addErrors(request, errs);
        }
    }

    /* (non-Javadoc)
     * @see com.adito.core.actions.CoreAction#getNavigationContext(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public int getNavigationContext(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
        return SessionInfo.ALL_CONTEXTS;
    }
}
TOP

Related Classes of com.adito.security.actions.ShowLogonAction

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.