Ejemplo n.º 1
0
  /**
   * Start the authentication process.
   *
   * @param scheme scheme
   * @param request request
   * @throws Exception on any error
   */
  public static void authenticate(AuthenticationScheme scheme, HttpServletRequest request)
      throws Exception {
    AuthenticationModule module = scheme.currentAuthenticationModule();
    if (module == null) {
      throw new Exception("No current authentication module");
    }
    RequestParameterMap params = new RequestParameterMap(new ServletRequestAdapter(request));
    User currentUser = scheme.getUser();
    LogonStateAndCache logonStateMachine =
        (LogonStateAndCache)
            request.getSession().getAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);

    if (logonStateMachine == null) {
      logonStateMachine =
          new LogonStateAndCache(LogonStateAndCache.STATE_STARTED, request.getSession());
    }

    if (logonStateMachine.getState()
        == LogonStateAndCache.STATE_KNOWN_USERNAME_NO_SCHEME_SPOOF_PASSWORD_ENTRY) {
      scheme.addCredentials(new PasswordCredentials("", "".toCharArray()));
    } else if (logonStateMachine.getState()
        == LogonStateAndCache.STATE_UNKNOWN_USERNAME_PROMPT_FOR_PASSWORD) {
      Credentials creds = module.authenticate(request, params);
      if (creds != null) scheme.addCredentials(creds);
    } else {
      Credentials creds = module.authenticate(request, params);
      if (creds != null) {
        scheme.addCredentials(creds);
        logonStateMachine.setState(LogonStateAndCache.STATE_VALID_LOGON);
      }
      // Check we have a user object
      if (currentUser == null && scheme.getUser() == null) {
        throw new Exception("The first authentication did not provide a user.");
      }
    }

    PolicyUtil.checkLogin(scheme.getUser());
  }
Ejemplo n.º 2
0
  public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    ActionMessages msgs = new ActionMessages();

    SessionInfo sessionInfo = LogonControllerFactory.getInstance().getSessionInfo(request);

    if (sessionInfo == null
        && request.getSession().getAttribute(Constants.SESSION_LOCKED) == null
        && LogonControllerFactory.getInstance().hasClientLoggedOn(request, response)
            == LogonController.LOGGED_ON) {
      if (log.isDebugEnabled()) log.debug(request.getRemoteHost() + " is already authenticated");

      return mapping.findForward("success");
    }

    /*
     * Get the authentication session and module to use to validate this
     * authentication attempt
     */
    AuthenticationScheme scheme =
        (AuthenticationScheme) request.getSession().getAttribute(Constants.AUTH_SESSION);
    LogonStateAndCache logonStateMachine =
        (LogonStateAndCache)
            request.getSession().getAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);

    // there are different users so we need to logon again, clearing the authentication scheme and
    // logon machine.
    if (sessionInfo != null
        && logonStateMachine != null
        && !sessionInfo.getUser().equals(logonStateMachine.getUser())) {
      request.getSession().removeAttribute(Constants.AUTH_SESSION);
      request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
      LogonControllerFactory.getInstance().logoffSession(request, response);
      msgs.add(
          Globals.ERROR_KEY,
          new ActionMessage("login.logonNotAllowed", "Session no longer valid, logon again."));
      saveErrors(request, msgs);
      return new RedirectWithMessages(mapping.findForward("logon"), request);
    }

    if (logonStateMachine == null) {
      logonStateMachine =
          new LogonStateAndCache(LogonStateAndCache.STATE_STARTED, request.getSession());
      request.getSession().setAttribute(LogonStateAndCache.LOGON_STATE_MACHINE, logonStateMachine);
    }
    if (scheme == null) {

      ActionForward fwd = null;
      try {
        fwd =
            ShowLogonAction.checkAuthSession(
                null, false, mapping, request, response, logonStateMachine);
      } catch (CoreException ce) {

      } catch (Throwable e) {
        log.error("Logon not allowed.", e);
        ActionMessages errs = new ActionMessages();
        if (e instanceof CoreException) {
          errs.add(Globals.ERROR_KEY, ((CoreException) e).getBundleActionMessage());
        } else {
          errs.add(
              Globals.ERROR_KEY,
              new ActionMessage("login.logonNotAllowed", "Please contact your administrator."));
        }
        saveErrors(request, errs);
        request.getSession().removeAttribute(Constants.AUTH_SESSION);
        request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
        if (form != null) form.reset(mapping, request);
        return new RedirectWithMessages(mapping.findForward("failed"), request);
      }
      if (fwd != null) {
        scheme = (AuthenticationScheme) request.getSession().getAttribute(Constants.AUTH_SESSION);
      }
    }

    if (scheme != null) {
      AuthenticationModule module = scheme.currentAuthenticationModule();
      if (module == null) {
        log.error("No authentication module.");
        request.getSession().removeAttribute(Constants.AUTH_SESSION);
        return mapping.findForward("logon");
      }

      try {
        // If there is no user in the scheme then it is an invalid login
        if (scheme.getUser() == null) {
          throw new InvalidLoginCredentialsException();
        }

        // Check the account is enabled and not locked
        if (!PolicyUtil.isEnabled(scheme.getUser())) {
          throw new AccountLockedException(scheme.getUsername(), "Account disabled.", true, 0);
        }

        // Check for locks
        LogonControllerFactory.getInstance()
            .checkForAccountLock(
                scheme.getUsername(), scheme.getUser().getRealm().getResourceName());

        // Authenticate
        authenticate(scheme, request);

        // Check logon is currently allowed
        String logonNotAllowedReason =
            LogonControllerFactory.getInstance().checkLogonAllowed(scheme.getUser());

        if (logonNotAllowedReason != null) {
          log.warn("Logon not allowed because '" + logonNotAllowedReason + "'");
          msgs.add(
              Globals.ERROR_KEY, new ActionMessage("login.logonNotAllowed", logonNotAllowedReason));
          saveErrors(request, msgs);
          return new RedirectWithMessages(mapping.findForward("logon"), request);
        }

        // Check for the next authentication modules
        AuthenticationModule nextModule = scheme.nextAuthenticationModule();
        if (nextModule != null
            && request.getSession().getAttribute(Constants.SESSION_LOCKED) == null) {
          if (log.isDebugEnabled())
            log.debug(
                "There are more authentication modules to satisfy (current mapping = "
                    + mapping.getPath());
          ActionForward fw = new RedirectWithMessages(mapping.findForward("logon"), request);
          return fw;
        }

        return finishAuthentication(scheme, request, response);
      } catch (InputRequiredException ex) {
        // The page wants to display or redirect somewhere
        if (ex.getForward() == null) return mapping.findForward("logon");
        else return ex.getForward();
      } catch (AccountLockedException ale) {
        return accountLocked(mapping, request, ale, msgs);
      } catch (InvalidLoginCredentialsException ex) {
        log.error("[" + request.getRemoteHost() + "] authentication failed", ex);

        LogonForm logonForm = (LogonForm) form;

        CoreServlet.getServlet()
            .fireCoreEvent(
                new CoreEvent(this, CoreEventConstants.LOGON, null, null, ex)
                    .addAttribute(
                        CoreAttributeConstants.EVENT_ATTR_IP_ADDRESS, request.getRemoteAddr())
                    .addAttribute(CoreAttributeConstants.EVENT_ATTR_HOST, request.getRemoteHost())
                    .addAttribute(CoreAttributeConstants.EVENT_ATTR_SCHEME, scheme.getSchemeName())
                    .addAttribute(
                        CoreAttributeConstants.EVENT_ATTR_ACCOUNT, logonForm.getUsername()));

        request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
        request.getSession().removeAttribute(Constants.AUTH_SESSION);

        try {
          scheme.setAccountLock(
              LogonControllerFactory.getInstance()
                  .logonFailed(
                      ((LogonForm) form).getUsername(),
                      ((LogonForm) form).getRealmName(),
                      scheme.getAccountLock()));
        } catch (AccountLockedException ale) {
          return accountLocked(mapping, request, ale, msgs);
        }

        msgs.add(Globals.ERROR_KEY, new ActionMessage("login.invalidCredentials"));
        saveErrors(request, msgs);
        return new RedirectWithMessages(mapping.findForward("logon"), request);
      } catch (Exception e) {
        log.error("Internal error authenticating.", e);
        msgs.add(
            Globals.ERROR_KEY, new BundleActionMessage("security", "login.error", e.getMessage()));
        saveErrors(request, msgs);
        request.getSession().setAttribute(Constants.EXCEPTION, e);
        request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
        request.getSession().removeAttribute(Constants.AUTH_SESSION);
        return new RedirectWithMessages(mapping.findForward("logon"), request);
      }
    } else {
      ActionMessages errs = new ActionMessages();
      errs.add(
          Globals.MESSAGE_KEY,
          new BundleActionMessage("security", "login.logonNotAllowed", "No scheme available."));
      saveErrors(request, errs);
      request.getSession().removeAttribute(LogonStateAndCache.LOGON_STATE_MACHINE);
      request.getSession().removeAttribute(Constants.AUTH_SESSION);
      if (form != null) form.reset(mapping, request);
      return new RedirectWithMessages(mapping.findForward("logon"), request);
    }
  }