Package com.adito.security

Source Code of com.adito.security.DefaultLogonController

        /*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
     
package com.adito.security;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.MessageResources;

import com.adito.boot.ContextHolder;
import com.adito.boot.DefaultPropertyDefinition;
import com.adito.boot.HostService;
import com.adito.boot.HttpConstants;
import com.adito.boot.PropertyClassManager;
import com.adito.boot.RequestHandlerRequest;
import com.adito.boot.RequestHandlerResponse;
import com.adito.boot.SystemProperties;
import com.adito.boot.Util;
import com.adito.core.CoreAttributeConstants;
import com.adito.core.CoreEvent;
import com.adito.core.CoreEventConstants;
import com.adito.core.CoreServlet;
import com.adito.core.CoreUtil;
import com.adito.core.GlobalWarning;
import com.adito.core.PageInterceptException;
import com.adito.core.PageInterceptListener;
import com.adito.core.ServletRequestAdapter;
import com.adito.core.ServletResponseAdapter;
import com.adito.core.UserDatabaseManager;
import com.adito.policyframework.PolicyDatabaseFactory;
import com.adito.policyframework.PolicyUtil;
import com.adito.policyframework.ResourceUtil;
import com.adito.properties.ProfilesFactory;
import com.adito.properties.ProfilesListDataSource;
import com.adito.properties.Property;
import com.adito.properties.PropertyProfile;
import com.adito.properties.impl.realms.RealmKey;
import com.adito.properties.impl.systemconfig.SystemConfigKey;
import com.adito.properties.impl.systemconfig.SystemConfiguration;
import com.adito.properties.impl.userattributes.UserAttributeKey;
import com.adito.realms.Realm;
import com.adito.security.actions.PromptForPrivateKeyPassphraseDispatchAction;
import com.adito.security.actions.UpdatePrivateKeyPassphraseDispatchAction;
import com.adito.setup.SystemInformationProvider;
import com.adito.setup.SystemInformationRegistry;
import com.adito.util.TicketGenerator;

/**
* This class is the default implementation of the
* {@link com.adito.security.LogonController} and maintains and validates
* all logons to Adito whether the be through the web based user
* interface or other sub-systems such as the <i>Embedded Client</i>.
*/
public class DefaultLogonController implements LogonController {
  protected static Log log = LogFactory.getLog(DefaultLogonController.class);
  private Map<String, SessionInfo> logons = new HashMap<String, SessionInfo>();
  Map<String, SessionInfo> logonsBySessionId = new HashMap<String, SessionInfo>();

  int sessionTimeoutBlockId;
  HashMap lockedUsers = new HashMap();
  List authenticationModules;
  HashMap authorizedTickets = new HashMap();

  /**
   * Constructor.
   */
  public DefaultLogonController() {
    lockedUsers = new HashMap();

    PropertyClassManager.getInstance()
            .getPropertyClass(SystemConfiguration.NAME)
            .registerPropertyDefinition(new DefaultPropertyDefinition(DefaultPropertyDefinition.TYPE_INTEGER,
                    "security.maxUserCount",
                    "",
                    99999,
                    "0",
                    2,
                    true));

    SystemInformationRegistry.getInstance().registerProvider(new MostUsersOnline());
    SystemInformationRegistry.getInstance().registerProvider(new CurrentUsersOnline());
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.security.LogonController#init()
   */
  public void init() {
      new HorribleHackReaperThread();
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.security.LogonController#isAdministrator(com.adito.policyframework.Principal)
   */
  public boolean isAdministrator(User principal) {
    // In setup mode everyone is an administrator
    if (ContextHolder.getContext().isSetupMode()) {
      return true;
    }
    try {
      // Now check the default administrators
      if (principal == null) {
        log.error("NULL principal object passed to isAdministrator!");
        return false;
      }

      if (principal.getPrincipalName() == null) {
        log.error("NULL principal name in principal object passed to isAdministrator!");
        return false;
      }

      List administrators = Property.getPropertyList(new RealmKey("security.administrators", principal.getRealm()
              .getRealmID()));

      for (Iterator it = administrators.iterator(); it.hasNext();) {
        if (principal.getPrincipalName().equals((String) it.next()))
          return true;
      }
    } catch (Exception e) {
      log.error("Failed to determine administrator status.", e);
    }
    return false;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.security.LogonController#addSessionTimeoutBlock(javax.servlet.http.HttpSession,
   *      java.lang.String)
   */
  public synchronized int addSessionTimeoutBlock(HttpSession session, String reason) {
    Map sessionTimeoutBlocks = (Map) session.getAttribute(Constants.SESSION_TIMEOUT_BLOCKS);
    if (sessionTimeoutBlocks == null) {
      sessionTimeoutBlocks = new HashMap();
      session.setAttribute(Constants.SESSION_TIMEOUT_BLOCKS, sessionTimeoutBlocks);
    }
    sessionTimeoutBlocks.put(String.valueOf(++sessionTimeoutBlockId), reason);
    if (log.isDebugEnabled())
      log.debug("Preventing session timeout on session " + session.getId()
        + " (id of "
        + sessionTimeoutBlockId
        + ") because '"
        + reason
        + "'. There are now "
        + sessionTimeoutBlocks.size()
        + " reasons not to timeout the session.");
    session.setMaxInactiveInterval(-1);
    return sessionTimeoutBlockId;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.security.LogonController#removeSessionTimeoutBlock(javax.servlet.http.HttpSession,
   *      int)
   */
  public synchronized void removeSessionTimeoutBlock(HttpSession session, int sessionTimeoutBlockId) {
    try {
      Map sessionTimeoutBlocks = (Map) session.getAttribute(Constants.SESSION_TIMEOUT_BLOCKS);
      if (sessionTimeoutBlocks != null) {
        String reason = (String) sessionTimeoutBlocks.get(String.valueOf(sessionTimeoutBlockId));
        if (reason == null) {
          log.warn("No session timeout block with id of " + sessionTimeoutBlockId);
        } else {
          sessionTimeoutBlocks.remove(String.valueOf(sessionTimeoutBlockId));
          if (log.isDebugEnabled())
            log.debug("Removing session timeout block " + sessionTimeoutBlockId
              + " for session "
              + session.getId()
              + " ('"
              + reason
              + "'). There are now "
              + sessionTimeoutBlocks.size()
              + " reasons not to timeout the session.");
        }
        if (sessionTimeoutBlocks.size() == 0) {
          session.removeAttribute(Constants.SESSION_TIMEOUT_BLOCKS);
          User user = (User) session.getAttribute(Constants.USER);
          int minutes = CoreUtil.getUsersProfilePropertyIntOrDefault(session, "webServer.sessionInactivityTimeout", user);
          if (log.isDebugEnabled())
            log.debug("Initialising timeout for session " + session.getId() + " to " + minutes + " minutes");
          session.setMaxInactiveInterval(minutes == 0 ? -1 : minutes * 60);
        }
      }
    } catch (IllegalStateException ise) {
      log.warn("Couldnt remove session timeout block.", ise);
    }
  }

  public void logoffSession(HttpServletRequest request, HttpServletResponse response) throws SecurityErrorException {
    if (log.isInfoEnabled())
      log.info("Logging off session " + request.getSession().getId());
    if (request.getSession().getAttribute(Constants.LOGON_TICKET) == null) {
      throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, "The current session does not contain a logon ticket");
    } else {
      String ticket = (String) request.getSession().getAttribute(Constants.LOGON_TICKET);
      SessionInfo session = getSessionInfo(ticket);
      logoff(ticket);

      if (request.getCookies() != null) {
        for (int i = 0; i < request.getCookies().length; i++) {
          Cookie cookie = request.getCookies()[i];
          if (cookie.getName().equals(Constants.LOGON_TICKET) || cookie.getName().equals(Constants.DOMAIN_LOGON_TICKET)) {
            cookie.setMaxAge(0);
            response.addCookie(cookie);
          }
        }
      }
      request.getSession().removeAttribute(Constants.LOGON_TICKET);
      session.invalidate();
    }
  }

  public List<SessionInfo> getSessionInfo(String username, int sessionType) {
    List<SessionInfo> info = null;
    for (Map.Entry<String, SessionInfo> entry : logons.entrySet()) {
      SessionInfo inf = (SessionInfo) entry.getValue();
      if (inf.getUser().getPrincipalName().equals(username) && (sessionType == -1 || (sessionType != -1 && sessionType == inf.getType()))) {
        if (info == null) {
          info = new ArrayList<SessionInfo>();
        }
        info.add(inf);
      }
    }
    return info;
  }

  public int getUserStatus(User user) throws Exception {
    if (user != null && lockedUsers.containsKey(user.getPrincipalName())
      && ((AccountLock) lockedUsers.get(user.getPrincipalName())).getLocks() > 0) {
      return ACCOUNT_LOCKED;
    } else if (getSessionInfo(user.getPrincipalName(), -1) != null) {
      return ACCOUNT_ACTIVE;
    } else {
      if (user == null) {
        return ACCOUNT_UNKNOWN;
      } else {
        boolean disabled = !PolicyUtil.isEnabled(user);
        // if (!admin && disabled) {
        if (disabled) {
          return ACCOUNT_DISABLED;
        } else {
          // boolean admin = isAdministrator(user, true, false, true);
          boolean logonAuthorized = PolicyUtil.canLogin(user);
          // if (!admin && !logonAuthorized) {
          if (!logonAuthorized) {
            return ACCOUNT_REVOKED;
          } else {
            return ACCOUNT_GRANTED;
          }
        }
      }
    }
  }

  private void checkForMultipleSessions(User user, InetAddress address, int sessionType) throws UserDatabaseException {
    int type = Property.getPropertyInt(new RealmKey("security.multipleSessions", user.getRealm().getResourceId()));
    List activeSessions;
    switch (type) {
      case 0:
        break; // No restrction
      case 1:
        activeSessions = getSessionInfo(user.getPrincipalName(), sessionType);
        if (activeSessions != null) {
          throw new UserDatabaseException("You are already logged on, and this systems policy is to only allow one session per user.");
        }
        break;
      case 2:
        activeSessions = getSessionInfo(user.getPrincipalName(), sessionType);
        if (activeSessions != null) {
          for (Iterator i = activeSessions.iterator(); i.hasNext();) {
            SessionInfo info = (SessionInfo) i.next();
            if (!info.getAddress().equals(address)) {
              throw new UserDatabaseException("You are already logged on at a different address, and this systems policy is to only allow one session per user / address.");
            }
          }
        }
        break;
      default:
        throw new UserDatabaseException("Unknown multiple session restrictions type " + type + ".");
    }
  }

  public void initialiseSession(HttpSession session, User user) throws UserDatabaseException {
    if (log.isInfoEnabled())
      log.info("Initialising session " + session.getId()
        + " with user "
        + (user == null ? "[none]" : user.getPrincipalName()));
    PropertyProfile profile = (PropertyProfile) session.getAttribute(Constants.SELECTED_PROFILE);
    session.setAttribute(Constants.USER, user);
    String logonInfo = MessageResources.getMessageResources("com.adito.navigation.ApplicationResources")
            .getMessage("footer.info",
              user.getPrincipalName(),
              SimpleDateFormat.getDateTimeInstance().format(new Date()));
    session.setAttribute(Constants.LOGON_INFO, logonInfo);
    try {
      List profiles = ResourceUtil.filterResources(user, ProfilesFactory.getInstance()
              .getPropertyProfiles(user.getPrincipalName(), true, user.getRealm().getResourceId()), true);
      session.setAttribute(Constants.PROFILES, profiles);
      if (profiles.size() == 0) {
        throw new UserDatabaseException("You do not have permission to use any profiles.");
      }
      String startupProfile = Property.getProperty(new UserAttributeKey(user, User.USER_STARTUP_PROFILE));
      if (profiles.size() < 2) {
        profile = (PropertyProfile) profiles.get(0);
      } else if (!startupProfile.equals(ProfilesListDataSource.SELECT_ON_LOGIN)) {
        int profileId = Integer.parseInt(startupProfile);
        profile = null;
        for (Iterator i = profiles.iterator(); i.hasNext();) {
          PropertyProfile p = (PropertyProfile) i.next();
          if (profileId == p.getResourceId()) {
            profile = p;
            break;
          }
        }
        if (profile == null) {
          profile = ProfilesFactory.getInstance().getPropertyProfile(null,
            "Default",
            UserDatabaseManager.getInstance().getDefaultUserDatabase().getRealm().getResourceId());
        }
      }
      if (profile != null) {
        if (log.isInfoEnabled())
          log.info("Switching user " + user.getPrincipalName() + " to profile " + profile.getResourceName());
        session.setAttribute(Constants.SELECTED_PROFILE, profile);
      }
    } catch (Exception e) {
      throw new UserDatabaseException("Failed to initialise profiles.", e);
    }
    final String logonTicket = (String) session.getAttribute(Constants.LOGON_TICKET);
    session.setAttribute(Constants.LOGOFF_HOOK, new HttpSessionBindingListener() {
      public void valueBound(HttpSessionBindingEvent evt) {
      }

      public void valueUnbound(HttpSessionBindingEvent evt) {
        if (log.isDebugEnabled())
          log.debug("Session unbound");
        // We should should only log off completely if no other
        // session has
        // the logon ticket
        SessionInfo currentTicketSessionInfo = ((SessionInfo) logons.get(logonTicket));
        if (currentTicketSessionInfo == null || evt.getSession().getId().equals(currentTicketSessionInfo.getHttpSession()
                .getId())) {
          if (log.isDebugEnabled())
            log.debug("Session (" + evt.getSession().getId()
              + ") unbound is the current session for ticket "
              + logonTicket
              + " so a logoff will be performed.");
          logoff(logonTicket);
        } else {
          if (log.isDebugEnabled())
            log.debug("Session unbound is NOT the current session, ignoring.");
        }
      }
    });
    if (log.isDebugEnabled())
      log.debug("Using profile: " + (profile == null ? "DEFAULT" : profile.getResourceName()) + ")");
    session.removeAttribute(Constants.SESSION_LOCKED);

    resetSessionTimeout(user, profile, session);
  }

  public void resetSessionTimeout(User user, PropertyProfile profile, HttpSession session) {
    try {
      Map sessionTimeoutBlocks = (Map) session.getAttribute(Constants.SESSION_TIMEOUT_BLOCKS);
      int minutes = 0;
      if (sessionTimeoutBlocks == null || sessionTimeoutBlocks.size() == 0) {
        minutes = CoreUtil.getUsersProfilePropertyIntOrDefault(session, "webServer.sessionInactivityTimeout", user);
      }
      if (log.isDebugEnabled())
        log.debug("Resetting timeout for session " + session.getId() + " to " + minutes + " minutes");
      session.setMaxInactiveInterval(minutes == 0 ? -1 : minutes * 60);
    } catch (Exception e) {
      log.error("Failed to reset session timeout.", e);
    }
  }

  public AccountLock checkForAccountLock(String username, String realmName) throws SecurityErrorException,
          AccountLockedException {
    // Get the user lockout policy
    int maxLogonAttemptsBeforeLock = 0;
    int lockDuration = 0;
    Realm realm;
    try {
      realm = UserDatabaseManager.getInstance().getRealm(realmName);
    } catch (Exception e1) {
      throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, e1, "Failed to determine the realm name " + realmName + ".");
    }

    try {
      maxLogonAttemptsBeforeLock = Property.getPropertyInt(new RealmKey("security.maxLogonAttemptsBeforeLock",
              realm.getResourceId()));
      lockDuration = Property.getPropertyInt(new RealmKey("security.lockDuration", realm.getResourceId()));
    } catch (Exception e) {
      throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, e, "Failed to determine password lockout policy.");
    }
    // Get the current lock (if any)
    AccountLock lock = "true".equals(SystemProperties.get("adito.recoveryMode", "false")) ? null
      : (AccountLock) lockedUsers.get(username);
    // If the user is currently locked, check if the lock has expired yeet
    if (lock != null && maxLogonAttemptsBeforeLock > 0 && lockDuration > 0 && lock.getLockedTime() != -1) {
      long expires = lock.getLockedTime() + (1000 * lockDuration);
      long now = System.currentTimeMillis();
      if (now < expires) {
        throw new AccountLockedException(username, "Account temporarily locked. Please try later.", false, expires - now);
      }
      // There was a lock, it is now expired
      lock.setAttempts(0);
      lock.setLockedTime(-1);
    }
    return lock;
  }

  // public User doClientLogon(String username, String password, String
  // realmName) throws UserDatabaseException,
  // InvalidLoginCredentialsException,
  // AccountLockedException {
  // // Get the user lockout policy
  // int maxLogonAttemptsBeforeLock = 0;
  // int maxLocksBeforeDisable = 0;
  // int lockDuration = 0;
  // try {
  // maxLogonAttemptsBeforeLock = Property.getPropertyInt(new
  // SystemConfigKey("security.maxLogonAttemptsBeforeLock"));
  // maxLocksBeforeDisable = Property.getPropertyInt(new
  // SystemConfigKey("security.maxLocksBeforeDisable"));
  // lockDuration = Property.getPropertyInt(new
  // SystemConfigKey("security.lockDuration"));
  // } catch (Exception e) {
  // throw new UserDatabaseException("Failed to determine password lockout
  // policy.", e);
  // }
  // // Get the current lock (if any)
  // AccountLock lock =
  // "true".equals(SystemProperties.get("adito.recoveryMode", "false")) ?
  // null
  // : (AccountLock) lockedUsers.get(username);
  // // If the user is currently locked, check if the lock has expired yeet
  // if (lock != null && maxLogonAttemptsBeforeLock > 0 && lockDuration > 0 &&
  // lock.getLockedTime() != -1) {
  // long expires = lock.getLockedTime() + (1000 * lockDuration);
  // long now = System.currentTimeMillis();
  // if (now < expires) {
  // throw new AccountLockedException("Account temporarily locked. Please try
  // later.", false, expires - now);
  // }
  // // There was a lock, it is now expired
  // lock.setAttempts(0);
  // lock.setLockedTime(-1);
  // }
  // try {
  // User user =
  // UserDatabaseManager.getInstance().getRealm(realmName).getUserDatabase().logon(username,
  // password);
  // // Sucessful login, remove any locks
  // unlockUser(username);
  // return user;
  // } catch (InvalidLoginCredentialsException ilce) {
  // if (lock == null && maxLogonAttemptsBeforeLock > 0 && lockDuration > 0) {
  // lock = createLock(username);
  // }
  // if (lock != null) {
  // lock.setAttempts(lock.getAttempts() + 1);
  // if (lock.getAttempts() >= maxLogonAttemptsBeforeLock) {
  // lock.setLocks(lock.getLocks() + 1);
  // if (lock.getLocks() >= maxLocksBeforeDisable) {
  // try {
  // // Disable the user
  // User user =
  // UserDatabaseManager.getInstance().getRealm(realmName).getUserDatabase().logon(username,
  // password);
  // if (PolicyUtil.isEnabled(user)) {
  // PolicyUtil.setEnabled(user, false, lock, null);
  // }
  // } catch (Exception e) {
  // log.error(e);
  // }
  // throw new AccountLockedException("Account disabled, please contact your
  // administrator.", true, 0);
  // } else {
  // lock.setLockedTime(System.currentTimeMillis());
  // throw new AccountLockedException("Account temporarily locked. Please try
  // later.", false,
  // lockDuration * 1000);
  // }
  // }
  // }
  // throw ilce;
  // } catch (AccountLockedException ale) {
  // throw ale;
  // } catch (Exception e) {
  // throw new UserDatabaseException("Failed to logon. ", e);
  // }
  // }

  public AccountLock logonFailed(String username, String realmName, AccountLock lock) throws SecurityErrorException,
          AccountLockedException {
    // Get the user lockout policy
    int maxLogonAttemptsBeforeLock = 0;
    int maxLocksBeforeDisable = 0;
    int lockDuration = 0;
    UserDatabase udb = null;
    try {
      udb = UserDatabaseManager.getInstance().getUserDatabase(realmName);
    } catch (Exception e1) {
      throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, e1, "Failed to determine the realm name " + realmName + ".");
    }

    try {
      maxLogonAttemptsBeforeLock = Property.getPropertyInt(new RealmKey("security.maxLogonAttemptsBeforeLock", udb.getRealm()
              .getResourceId()));
      maxLocksBeforeDisable = Property.getPropertyInt(new RealmKey("security.maxLocksBeforeDisable", udb.getRealm()
              .getResourceId()));
      lockDuration = Property.getPropertyInt(new RealmKey("security.lockDuration", udb.getRealm().getResourceId()));
    } catch (Exception e) {
      throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, e, "Failed to determine password lockout policy.");
    }
    if (lock == null && maxLogonAttemptsBeforeLock > 0 && lockDuration > 0) {
      lock = createLock(username);
    }
    if (lock != null) {
      lock.setAttempts(lock.getAttempts() + 1);
      if (lock.getAttempts() >= maxLogonAttemptsBeforeLock) {
        lock.setLocks(lock.getLocks() + 1);
        if (lock.getLocks() >= maxLocksBeforeDisable) {
          try {
            // Disable the user
            User user = udb.getAccount(username);
            if (PolicyUtil.isEnabled(user)) {
              PolicyUtil.setEnabled(user, false, lock, null);
            }
          } catch (Exception e) {
            log.error(e);
          }
          throw new AccountLockedException(username, "Account disabled, please contact your administrator.", true, 0);
        } else {
          lock.setLockedTime(System.currentTimeMillis());
          throw new AccountLockedException(username, "Account temporarily locked. Please try later.", false, lockDuration * 1000);
        }
      }
    }
    return lock;
  }

  public void logoff(String ticket) {

    SessionInfo session = (SessionInfo) logons.remove(ticket);
    /**
     * LDP - What happens if logoff is called twice? Previously we assumed this
     * would never happen
     */
    if(session==null)
      return;
   
    if (log.isInfoEnabled())
      log.info("Logging off " + ticket);
    List<String> ticketsToRemove = new ArrayList<String>();
    synchronized (logonsBySessionId) {
      for (Map.Entry<String, SessionInfo> entry : logonsBySessionId.entrySet()) {
        if (entry.getValue().getLogonTicket().equals(ticket)) {
          ticketsToRemove.add(entry.getKey());
        }
      }
      for (String key : ticketsToRemove) {
        logonsBySessionId.remove(key);
      }
    }
        session.release();
    CoreServlet.getServlet().fireCoreEvent(new CoreEvent(this, CoreEventConstants.LOGOFF, null, session));
  }

  public Map getActiveSessions() {
    return logons;
  }

  public User getUser(HttpSession session, String logonTicket) throws SecurityErrorException {
    if (logonTicket == null) {
      logonTicket = (String) session.getAttribute(Constants.LOGON_TICKET);
    }
    if (logonTicket == null) {
      throw new SecurityErrorException(SecurityErrorException.ERR_INVALID_TICKET, "No ticket was provided or found in the session object (" + session.getId() + ")");
    }
    SessionInfo info = (SessionInfo) logons.get(logonTicket);
    if (info == null) {
      throw new SecurityErrorException(SecurityErrorException.ERR_INVALID_TICKET, "No session info. object could be found for the ticket (" + session.getId() + ")");
    }
    User user = info.getUser();
    return user;
  }

  public User getUser(HttpServletRequest request) throws SecurityErrorException {
    return getUser(request, null);
  }

  public User getUser(HttpServletRequest request, String logonTicket) throws SecurityErrorException {
    return getUser(request.getSession(), logonTicket);
  }

  public int hasClientLoggedOn(HttpServletRequest request, HttpServletResponse response) throws SecurityErrorException {
    // Get the logon cookie
    String logonCookie = null;
    if (request.getCookies() != null) {
      for (int i = 0; i < request.getCookies().length; i++) {
        Cookie cookie = request.getCookies()[i];
        if (cookie.getName().equals(Constants.LOGON_TICKET) || cookie.getName().equals(Constants.DOMAIN_LOGON_TICKET)) {
          logonCookie = cookie.getValue();
        }
      }
    }
    // If there is a logon ticket in the requests attributes then reassign
    // as we've just been issued a new ticket.
    if (request.getAttribute(Constants.LOGON_TICKET) != null)
      logonCookie = (String) request.getAttribute(Constants.LOGON_TICKET);
    // First check the users session for a logonticket
    String sessionLogonTicket = (String) request.getSession().getAttribute(Constants.LOGON_TICKET);
    if (sessionLogonTicket != null) {
      // Make sure we are still receiving the logon ticket
      /**
       * LDP - Users are having too many issues with this change. If we
       * still have a ticket in the session then the HTTP session must
       * still be alive and the the cookie has simply expired before the
       * HTTP session (or the browser has elected not to send it). We
       * should allow this to continue and refresh the cookie here.
       */
      /*
       * if(logonCookie == null &&
       * request.getAttribute(Constants.LOGON_TICKET) == null) {
       *
       *
       * log.warn("Lost logon ticket. It is likely that logon cookie has
       * expired. "); return INVALID_TICKET; } else
       */
      if (logonCookie == null) {

        SessionInfo session = getSessionInfo(sessionLogonTicket);
        if (session == null)
          return NOT_LOGGED_ON;
        addCookies(new ServletRequestAdapter(request), new ServletResponseAdapter(response), sessionLogonTicket, session);
      }
      // Still check that the cookie is what we expect it to be
      if (logonCookie != null && !sessionLogonTicket.equals(logonCookie)) {
        log.warn("Expected a different logon ticket.");
        return NOT_LOGGED_ON;
      }
     
      if(checkRemoteAddress(sessionLogonTicket, request.getRemoteAddr())) {
        return LOGGED_ON;
      }
    } else {
      if (logonCookie != null && logons.containsKey(logonCookie)) {
        if(checkRemoteAddress(logonCookie, request.getRemoteAddr())) {
          refreshLogonTicket(request, response, logonCookie);
          return LOGGED_ON;
        }
      }
    }
    return NOT_LOGGED_ON;
  }
 
  private boolean checkRemoteAddress(String logonTicket, String remoteAddr) {

    try {
      SessionInfo session = getSessionInfo(logonTicket);
     
      if(Property.getPropertyBoolean(new RealmKey("security.checkRemoteAddress", session.getRealmId()))) {
        InetAddress addr = InetAddress.getByName(remoteAddr);
        if(log.isDebugEnabled())
          log.debug("Verifying " + addr.getHostAddress() + " is original address " + session.getAddress().getHostAddress());
        return session!=null && session.getAddress().equals(addr);
      } else
        return true;

    } catch (UnknownHostException e) {
      log.error("Failed to determine remote address", e);
      return false;
    }
  }

  private void refreshLogonTicket(HttpServletRequest request, HttpServletResponse response, String logonTicket)
          throws SecurityErrorException {
    if (log.isInfoEnabled())
      log.info("Refreshing logon ticket " + logonTicket);
    User user = getUser(request, logonTicket);
    request.getSession().setAttribute(Constants.USER, user);
    request.getSession().setAttribute(Constants.LOGON_TICKET, logonTicket);
    request.setAttribute(Constants.LOGON_TICKET, logonTicket);
    SessionInfo info = (SessionInfo) logons.get(logonTicket);
    if (info == null) {
      InetAddress address;
      try {
        address = InetAddress.getByName(request.getRemoteAddr());
      } catch (UnknownHostException uhe) {
        throw new SecurityErrorException(SecurityErrorException.ERR_INVALID_TICKET, "Could not refresh logon ticket. " + uhe.getMessage());
      }
      String userAgent = request.getHeader("User-Agent");
      info = SessionInfo.nextSession(request.getSession(), logonTicket, user, address, SessionInfo.UI, userAgent);
    } else {
      moveSessionTimeoutBlocks(info.getHttpSession(), request.getSession());
      info.setSession(request.getSession());
    }
    request.getSession().setAttribute(Constants.SESSION_INFO, info);

    /**
     * LDP - Allow for the session info to be looked up using the session
     * id.
     */
    try {
      String sessionIdentifier = SystemProperties.get("adito.cookie", "JSESSIONID");
      String sessionId = null;
      Cookie[] cookies = request.getCookies();
      for (int i = 0; i < cookies.length; i++) {
        if (cookies[i].getName().equalsIgnoreCase(sessionIdentifier)) {
          sessionId = cookies[i].getValue();
          break;
        }
      }
      if (sessionId != null) {
        logonsBySessionId.put(sessionId, info);
      } else
        log.warn("Could not find session id using identifier " + sessionIdentifier + " in HTTP request");
    } catch (Exception ex) {
      log.warn("Failed to determine HTTP session id", ex);
    }
    addSession(logonTicket, info, request, response);
    try {
      if (Property.getPropertyBoolean(new SystemConfigKey("security.session.lockSessionOnBrowserClose"))) {
        if (log.isInfoEnabled())
          log.info("New session - will force the user to authenticate again");
        request.getSession().setAttribute(Constants.SESSION_LOCKED, user);
      }
      else {
          ResourceUtil.setAvailableProfiles(info);
      }
    } catch (Exception e) {
      log.warn("Failed to set session lock.", e);
    }
  }

  public void addSession(String logonTicket, SessionInfo info, HttpServletRequest request, HttpServletResponse response) {
    logons.put(logonTicket, info);
    addCookies(new ServletRequestAdapter(request), new ServletResponseAdapter(response), logonTicket, info);
  }

  public void addCookies(RequestHandlerRequest request, RequestHandlerResponse response, String logonTicket, SessionInfo session) {
   
   
    if(request.getAttribute("sslx.logon.cookie")!=null)
      return;
   
    /**
     * Set the normal logon ticket without a domain - this works in almost
     * all circumstances
     */
    Cookie cookie = new Cookie(Constants.LOGON_TICKET, logonTicket);
    cookie.setMaxAge(Property.getPropertyInt(new SystemConfigKey("security.session.maxCookieAge")));
    cookie.setPath("/");
    cookie.setSecure(true);
    response.addCookie(cookie);
    /**
     * Set a logon ticket for the domain - this is require to make active
     * dns work.
     */
    Cookie cookie2 = new Cookie(Constants.DOMAIN_LOGON_TICKET, logonTicket);
    cookie2.setMaxAge(Property.getPropertyInt(new SystemConfigKey("security.session.maxCookieAge")));
    cookie2.setPath("/");
    // We now set the domain on the cookie so the new Active DNS feature for
    // Reverse Proxy works correctly
    String host = request.getField("Host");
    if (host != null) {
      HostService hostService = new HostService(host);
      cookie2.setDomain(hostService.getHost());
    }
    cookie2.setSecure(true);
    response.addCookie(cookie2);
   
   
    request.setAttribute("sslx.logon.cookie", new Object());
   
    /**
     * LDP - This code was not setting the domain on the ticket. I've
     * converted to the new format of having two seperate tickets to ensure
     * tickets are sent across domains
     */
    /*
     * Cookie cookie = new Cookie(Constants.LOGON_TICKET, logonTicket); try {
     * cookie.setMaxAge(Integer.parseInt(CoreServlet.getServlet().getPropertyDatabase().getProperty(0,
     * null, "security.session.maxCookieAge"))); if
     * ("true".equals(CoreServlet.getServlet().getPropertyDatabase().getProperty(0,
     * null, "security.session.lockSessionOnBrowserClose"))) { if
     * (log.isInfoEnabled()) log.info("New session - will force the user to
     * authenticate again"); // initialiseSession(request.getSession(),
     * user); // List profiles = //
     * CoreServlet.getServlet().getPropertyDatabase().getPropertyProfiles(user.getUsername(), //
     * false); // request.getSession().setAttribute(Constants.PROFILES, //
     * profiles);
     * request.getSession().setAttribute(Constants.SESSION_LOCKED, user); } }
     * catch (Exception e) { log.error(e); cookie.setMaxAge(900); }
     * cookie.setPath("/"); cookie.setSecure(true);
     * response.addCookie(cookie);
     */
    //
  }

  private SessionInfo addLogonTicket(HttpServletRequest request, HttpServletResponse response, User user, InetAddress address,
                    int sessionType) {
    String logonTicket = TicketGenerator.getInstance().generateUniqueTicket("SLX");
    if (log.isInfoEnabled())
      log.info("Adding logon ticket to session " + request.getSession().getId());
    request.getSession().setAttribute(Constants.LOGON_TICKET, logonTicket);
    request.setAttribute(Constants.LOGON_TICKET, logonTicket);
    String userAgent = request.getHeader("User-Agent");
    SessionInfo info = SessionInfo.nextSession(request.getSession(), logonTicket, user, address, sessionType, userAgent);
    request.getSession().setAttribute(Constants.SESSION_INFO, info);
    try {
      String sessionIdentifier = SystemProperties.get("adito.cookie", "JSESSIONID");
      String sessionId = null;
      Cookie[] cookies = request.getCookies();
      for (int i = 0; cookies != null && i < cookies.length; i++) {
        if (cookies[i].getName().equalsIgnoreCase(sessionIdentifier)) {
          sessionId = cookies[i].getValue();
          break;
        }
      }
      if (sessionId != null) {
        logonsBySessionId.put(sessionId, info);
      } else
        log.warn("Could not find session id using identifier " + sessionIdentifier + " in HTTP request");
    } catch (Exception ex) {
      log.warn("Failed to determine HTTP session id", ex);
    }
    logons.put(logonTicket, info);
    /**
     * Set the normal logon ticket without a domain - this works in almost
     * all circumstances
     */
    Cookie cookie = new Cookie(Constants.LOGON_TICKET, logonTicket);
    cookie.setMaxAge(Property.getPropertyInt(new SystemConfigKey("security.session.maxCookieAge")));
    cookie.setPath("/");
    cookie.setSecure(true);
    response.addCookie(cookie);
    /**
     * Set a logon ticket for the domain - this is require to make active
     * dns work.
     */
    Cookie cookie2 = new Cookie(Constants.DOMAIN_LOGON_TICKET, logonTicket);
    cookie2.setMaxAge(Property.getPropertyInt(new SystemConfigKey("security.session.maxCookieAge")));
    cookie2.setPath("/");
    // We now set the domain on the cookie so the new Active DNS feature for
    // Reverse Proxy works correctly
    String host = request.getHeader("Host");
    if (host != null) {
      HostService hostService = new HostService(host);
      cookie2.setDomain(hostService.getHost());
    }
    cookie.setSecure(true);
    response.addCookie(cookie2);
    return info;
  }

  public void unlockUser(String username) {
    if (log.isInfoEnabled())
      log.info("Unlocking user " + username);
    lockedUsers.remove(username);
  }

  /**
   * @param request
   * @param response
   * @param scheme
   */
  public void logon(HttpServletRequest request, HttpServletResponse response, AuthenticationScheme scheme) throws Exception {
    User user = scheme.getUser();

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

    if (logonNotAllowedReason != null) {
      log.warn("Logon not allowed because '" + logonNotAllowedReason + "'");
      throw new Exception(logonNotAllowedReason);
    }

    if (log.isInfoEnabled()) {
      log.info("Session logon ticket is " + (String) request.getSession().getAttribute(Constants.LOGON_TICKET));
      log.info("Logging on " + scheme.getUsername() + " for scheme " + scheme.getSchemeName());
    }
    // Sucessful login, remove any locks
    unlockUser(scheme.getUsername());

    String host = (request.isSecure() || SystemProperties.get("jetty.force.HTTPSRedirect", "false").equals("true") ? "https"
      : "http") + "://"
      + request.getHeader(HttpConstants.HDR_HOST);

    request.getSession().setAttribute(Constants.HOST, host);
    SessionInfo info = null;
    boolean fireEvent = false;
    if (request.getSession().getAttribute(Constants.SESSION_LOCKED) == null) {
      InetAddress address = InetAddress.getByName(request.getRemoteAddr());
      int sessionType = SessionInfo.getSessionTypeForUserAgent(request.getHeader("User-Agent"));
      checkForMultipleSessions(user, address, sessionType);
      info = addLogonTicket(request, response, user, address, sessionType);
      try {
        info.getHttpSession().setAttribute(Constants.VPN_AUTOSTART,
          CoreUtil.getUsersProfileProperty(info.getHttpSession(), "client.autoStart", user));
      } catch (Exception e) {
        throw new SecurityErrorException(SecurityErrorException.INTERNAL_ERROR, e.getMessage());
      }
      fireEvent = true;
    }
    // Initialise the session
    initialiseSession(request.getSession(), user);
    // Build the menus
    CoreUtil.resetMainNavigation(request.getSession());

    char[] pw = getPasswordFromCredentials(scheme);
    String mode = Property.getProperty(new SystemConfigKey("security.privateKeyMode"));
    if (!mode.equals("disabled")) {

      try {
        PublicKeyStore.getInstance().verifyPrivateKey(user.getPrincipalName(), pw);
      } catch (PromptForPasswordException e) {
        CoreUtil.addPageInterceptListener(request.getSession(), new PromptForPrivateKeyPassphraseInterceptListener());
      } catch (UpdatePrivateKeyPassphraseException e) {
        if (mode.equals("prompt")) {
          CoreUtil.addPageInterceptListener(request.getSession(), new PromptForPrivateKeyPassphraseInterceptListener());
        } else {
          CoreUtil.addPageInterceptListener(request.getSession(), new UpdatePrivateKeyPassphraseInterceptListener());
        }
      }
        }

    /*
     * Make sure the logon event gets fired after the private key has
     * been initialised. This is repeated in the actions the page
     * intercept listeners redirect to
     */
    if (fireEvent) {
      CoreServlet.getServlet()
              .fireCoreEvent(new CoreEvent(this, CoreEventConstants.LOGON, scheme, info).addAttribute(CoreAttributeConstants.EVENT_ATTR_IP_ADDRESS,
                request.getRemoteAddr())
                      .addAttribute(CoreAttributeConstants.EVENT_ATTR_HOST, request.getRemoteHost())
                      .addAttribute(CoreAttributeConstants.EVENT_ATTR_SCHEME, scheme.getSchemeName()));
    }
  }

  /**
   * @param scheme
   * @return
   */
  public char[] getPasswordFromCredentials(AuthenticationScheme scheme) {

    if (scheme != null) {
      for (Iterator i = scheme.credentials(); i.hasNext();) {
        Credentials cred = (Credentials) i.next();

        if (cred instanceof PasswordCredentials) {
          if (((PasswordCredentials) cred).getPassword() != null) {
            return ((PasswordCredentials) cred).getPassword();
          }
        }
      }
    }
    return null;
  }

  public SessionInfo getSessionInfo(HttpServletRequest request) {
    /**
     * LDP - This was only ever looking at the HTTP session. This causes
     * problems if the browser creates a new session but the logon ticket is
     * still valid. Look at the cookies if the ticket cannot be found.
     */

      /**
       * BPS - This is wrong and should be solved another way.
       * getSessionInfo is *supposed* to return null if the HttpSession is
       * not attached to a SessionInfo. This code is only partially
       * reconfiguring the session and will prevent hasClientLoggedOn
       * from completing its job properly. This is a possible culprit for
       * the SessionInfos hanging around as the session
       * binding listeners will not be set up correctly.
       */
    SessionInfo session = getSessionInfo(request.getSession());

    if (session == null) {
      Cookie[] cookies = request.getCookies();
      if (cookies != null) {
        for (int i = 0; i < cookies.length; i++) {
          if (cookies[i].getName().equals(Constants.LOGON_TICKET) || cookies[i].getName()
                  .equals(Constants.DOMAIN_LOGON_TICKET)) {
            session = getSessionInfo(cookies[i].getValue());
            if (session != null) {
                            log.error("----------------------------------------------------------");
                            log.error("A call has been made to getSessionInfo(HttpServletRequest)");
                            log.error("but the SessionInfo was not contained in the HttpSession");
                            log.error("However, there appears to valid cookies that DO point to a");
                            log.error("valid SessionInfo.");
                            dumpSessionStuff(session);
              request.getSession().setAttribute(Constants.LOGON_TICKET, session.getLogonTicket());
              request.getSession().setAttribute(Constants.SESSION_INFO, session);
              break;
            }
          }
        }
      }
    }

    return session;
  }

  public SessionInfo getSessionInfo(HttpSession session) {
    String logonTicket = (String) session.getAttribute(Constants.LOGON_TICKET);
    if (logonTicket != null) {
      return getSessionInfo(logonTicket);
    }
    return null;
  }

  public SessionInfo getSessionInfoBySessionId(String sessionId) {
    return (SessionInfo) logonsBySessionId.get(sessionId);
  }

  public SessionInfo getSessionInfo(String logonTicket) {
    return (SessionInfo) logons.get(logonTicket);
  }

  public void attachSession(String sessionId, SessionInfo session) {
    logonsBySessionId.put(sessionId, session);
  }

  public void registerAuthorizationTicket(String ticket, SessionInfo session) {
    authorizedTickets.put(ticket, session);
  }

  public SessionInfo removeAuthorizationTicket(String ticket) {
    return (SessionInfo) authorizedTickets.remove(ticket);
  }

  public SessionInfo getAuthorizationTicket(String ticket) {
    return (SessionInfo) authorizedTickets.get(ticket);
  }

  AccountLock createLock(String username) {
    AccountLock lock = new AccountLock(username);
    lockedUsers.put(username, lock);
    return lock;
  }

  public String checkLogonAllowed(User user) {

    updateMostUsersEverOnline();
    return null;
  }

  private synchronized void moveSessionTimeoutBlocks(HttpSession oldSession, HttpSession newSession) {
    Map sessionTimeoutBlocks = (Map) oldSession.getAttribute(Constants.SESSION_TIMEOUT_BLOCKS);
    if (sessionTimeoutBlocks != null) {
      newSession.setAttribute(Constants.SESSION_TIMEOUT_BLOCKS, sessionTimeoutBlocks);
    }
    Integer vpnClientSessionTimeoutBlockId = (Integer) oldSession.getAttribute(Constants.AGENT_SESSION_TIMEOUT_BLOCK_ID);
    if (vpnClientSessionTimeoutBlockId != null) {
      newSession.setAttribute(Constants.AGENT_SESSION_TIMEOUT_BLOCK_ID, vpnClientSessionTimeoutBlockId);
    }
    newSession.setMaxInactiveInterval(sessionTimeoutBlocks == null || sessionTimeoutBlocks.size() == 0 ? oldSession.getMaxInactiveInterval()
      : -1);
  }

  public static class UpdatePrivateKeyPassphraseInterceptListener implements PageInterceptListener {

    public String getId() {
      return "updatePrivateKeyPassphrase";
    }

    public ActionForward checkForForward(Action action, ActionMapping mapping, HttpServletRequest request,
                        HttpServletResponse response) throws PageInterceptException {
      if (!(action instanceof UpdatePrivateKeyPassphraseDispatchAction)) {
        return new ActionForward("/updatePrivateKeyPassphrase.do", true);
      }
      return null;
    }

    public boolean isRedirect() {
      return false;
    }
  }

  class PromptForPrivateKeyPassphraseInterceptListener implements PageInterceptListener {

    public String getId() {
      return "promptForPrivateKeyPassphrase";
    }

    public ActionForward checkForForward(Action action, ActionMapping mapping, HttpServletRequest request,
                        HttpServletResponse response) throws PageInterceptException {
      if (!(action instanceof PromptForPrivateKeyPassphraseDispatchAction)) {
        try {
          if ("automatic".equals(Property.getProperty(new SystemConfigKey("security.privateKeyMode")))) {
            return new ActionForward("/promptForPrivateKeyPassphraseAuto.do", true);
          } else {
            return new ActionForward("/promptForPrivateKeyPassphrase.do", true);
          }
        } catch (Exception e) {
          log.error("Failed to determine private key mode.", e);
        }
      }
      return null;
    }

    public boolean isRedirect() {
      return false;
    }
  }

  protected int getActiveSessionCount() {
    return getActiveSessions().size();
  }

  protected void updateMostUsersEverOnline() {

    try {
      int concurrentSessions = getActiveSessionCount() + 1;
      if (Property.getPropertyInt(new SystemConfigKey("security.maxUserCount")) < (concurrentSessions)) {
        Property.setProperty(new SystemConfigKey("security.maxUserCount"), concurrentSessions, null);
      }
    } catch (Exception ex) {
      log.error("Could not update most users online property", ex);
    }
  }
 
  //////// TEMPORARY CODE ///////////

    private void dumpSessionStuff(SessionInfo sesh) {
        log.error("User: " + sesh.getUser().getPrincipalName());
        log.error("Type: " + sesh.getType());
        log.error("User Agent: " + sesh.getUserAgent());
        log.error("Address: " + sesh.getAddress());
        log.error("Logon Time: " + SimpleDateFormat.getDateTimeInstance().format(new Date(sesh.getLogonTime().getTimeInMillis())));
        log.error("------------------------------------------------------");
    }

  class MostUsersOnline implements SystemInformationProvider {
    public String getBundle() {
      return "security";
    }

    public String getName() {
      return "security.maxUserCount";
    }

    public String getValue() {
      return String.valueOf(Property.getProperty(new SystemConfigKey("security.maxUserCount")));
    }
  }

  class CurrentUsersOnline implements SystemInformationProvider {
    public String getBundle() {
      return "security";
    }

    public String getName() {
      return "security.currentUserCount";
    }

    public String getValue() {
      return String.valueOf(getActiveSessionCount());
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see com.adito.security.LogonController#applyMenuItemChanges(javax.servlet.http.HttpServletRequest)
   */
  public void applyMenuItemChanges(HttpServletRequest request) {
    for (Iterator i = logons.entrySet().iterator(); i.hasNext();) {
      Map.Entry entry = (Map.Entry) i.next();
      SessionInfo sessionInfo = (SessionInfo) entry.getValue();
      if (sessionInfo.getType() == SessionInfo.UI) {
          try {
            // remove the menu tree.
            sessionInfo.getHttpSession().removeAttribute(Constants.MENU_TREE);
            String username = sessionInfo.getUser().getPrincipalName();
          // clean up any policy setups as they have changed now.
          PolicyDatabaseFactory.getInstance().cleanup();
          Realm realm = sessionInfo.getUser().getRealm();
          // update the sessions user, so any changes are known.
          sessionInfo.setUser(UserDatabaseManager.getInstance().getUserDatabase(realm).getAccount(username));
        } catch (Exception e) {
        }
      }
    }
  }
 
  /**
   * This thread is a temporary fix until we can find where SessionInfo
   * objects are not getting removed from the list of active sessions when
   * an HttpSession gets invalidated
   */
  class HorribleHackReaperThread extends Thread {
     
      HorribleHackReaperThread() {
          super("HorribleHackReaperThread");
          setPriority(Thread.MIN_PRIORITY);
          setDaemon(true);
          start();
      }
     
      public void run() {
          try {
              while(true) {
                  Thread.sleep(60000);
                  Map sessions = getActiveSessions();
                  synchronized(sessions) {
                      List<SessionInfo> toRemove = new ArrayList<SessionInfo>();
                      for(Iterator i = sessions.values().iterator(); i.hasNext(); ) {
                          SessionInfo sesh = (SessionInfo)i.next();
                          if(sesh.getHttpSession() != null) {
                              try {
                                  sesh.getHttpSession().getAttribute(Constants.SESSION_INFO);
                              }
                              catch(IllegalStateException ise) {
                                  log.error("------------------------------------------------------");
                                  log.error("An Adito session that is attached to an");
                                  log.error("invalid HttpSession has been discovered. This");
                                    log.error("may cause other problems so it has been removed.");
                                    log.error("Please report this 3SP together with the information");
                                    log.error("displayed below so that we determine the underlying");
                                    log.error("cause of this problem.");
                                    dumpSessionStuff(sesh);
                                    toRemove.add(sesh);
                              }
                          }
                      }
                      for(SessionInfo sesh : toRemove) {
                            logons.remove(sesh.getLogonTicket());
                            logonsBySessionId.remove(sesh.getHttpSession().getId());
                      }
                  }                 
              }
          }
          catch(Exception e) {
              log.error("SessionInfo reaper thread has died.", e);
          }
      }
  }
}
TOP

Related Classes of com.adito.security.DefaultLogonController

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.