Beispiel #1
0
  private Authentication fresh(Authentication authentication, ServletRequest req) {
    HttpServletRequest request = (HttpServletRequest) req;

    HttpSession session = request.getSession(false);

    if (session != null) {
      SessionRegistry sessionRegistry =
          (SessionRegistry) SpringBeanUtil.getBeanByName("sessionRegistry");
      SessionInformation info = sessionRegistry.getSessionInformation(session.getId());

      if (info != null) {
        // Non-expired - update last request date/time
        Object principal = info.getPrincipal();
        if (principal instanceof org.springframework.security.core.userdetails.User) {
          org.springframework.security.core.userdetails.User userRefresh =
              (org.springframework.security.core.userdetails.User) principal;
          ServletContext sc = session.getServletContext();
          HashSet<String> unrgas = springSecurityService.getUsersNeedRefreshGrantedAuthorities();
          if (unrgas.size() > 0) {
            HashSet<String> loginedUsernames = new HashSet<String>();

            List<Object> loggedUsers = sessionRegistry.getAllPrincipals();
            for (Object lUser : loggedUsers) {
              if (lUser instanceof org.springframework.security.core.userdetails.User) {
                org.springframework.security.core.userdetails.User u =
                    (org.springframework.security.core.userdetails.User) lUser;
                loginedUsernames.add(u.getUsername());
              }
            }
            // 清除已经下线的但需要刷新的username
            for (Iterator iterator = unrgas.iterator(); iterator.hasNext(); ) {
              String unrgs = (String) iterator.next();
              if (!loginedUsernames.contains(unrgs)) {
                iterator.remove();
              }
            }
            if (unrgas.contains(userRefresh.getUsername())) {
              // 如果需要刷新权限的列表中有当前的用户,刷新登录用户权限
              // FIXME:与springSecurityServiceImpl中的功能,相重复,需重构此方法和springSecurityServiceImpl
              MyJdbcUserDetailsManager mdudm =
                  (MyJdbcUserDetailsManager)
                      SpringBeanUtil.getBeanByType(MyJdbcUserDetailsManager.class);
              SecurityContextHolder.getContext()
                  .setAuthentication(
                      new UsernamePasswordAuthenticationToken(
                          userRefresh,
                          userRefresh.getPassword(),
                          mdudm.getUserAuthorities(userRefresh.getUsername())));
              session.setAttribute(
                  HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
                  SecurityContextHolder.getContext());
              unrgas.remove(userRefresh.getUsername());
              return SecurityContextHolder.getContext().getAuthentication();
            }
          }
        }
      }
    }
    return authentication;
  }
 @Override
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
   final Usuario usr = this.dao.findById(username);
   if (usr == null) {
     throw new UsernameNotFoundException(username);
   }
   logger.debug("Usr: {}", usr);
   for (final Object o : this.sessionRegistry.getAllPrincipals()) {
     if (((Usuario) o).getCpf().equals(username)) {
       for (final SessionInformation si : this.sessionRegistry.getAllSessions(o, true)) {
         si.expireNow();
       }
     }
   }
   return usr;
 }
  public static User getUser(String sessionID) {
    User user = null;
    if (sessionRegistry == null) {
      sessionRegistry = SpringContextUtils.getBean("sessionRegistry");
    }
    if (sessionRegistry == null) {
      log.debug("没有从spring中获取到sessionRegistry");
      return null;
    }
    SessionInformation info = sessionRegistry.getSessionInformation(sessionID);
    if (info == null) {
      log.debug("没有获取到会话ID为:" + sessionID + " 的在线用户");
      return null;
    }
    user = (User) info.getPrincipal();
    log.debug("获取到会话ID为:" + sessionID + " 的在线用户");

    return user;
  }
  @Override
  public void contextDestroyed(ServletContextEvent sce) {
    // 在容器销毁时把未正常结束遗留的登录记录信息强制设置登出时间
    logger.info("ServletContext destroy force setup session user logout time...");

    UserLogonLogService userLogonLogService =
        SpringContextHolder.getBean(UserLogonLogService.class);
    GroupPropertyFilter groupPropertyFilter = new GroupPropertyFilter();
    groupPropertyFilter.and(new PropertyFilter(MatchType.NU, "logoutTime", Boolean.TRUE));
    List<UserLogonLog> userLogonLogs = userLogonLogService.findByFilters(groupPropertyFilter);
    if (!CollectionUtils.isEmpty(userLogonLogs)) {

      Set<String> sessionIdSet = new HashSet<String>();
      SessionRegistry sessionRegistry = SpringContextHolder.getBean(SessionRegistry.class);
      List<Object> principals = sessionRegistry.getAllPrincipals();
      for (Object principal : principals) {
        List<SessionInformation> sessionInformations =
            sessionRegistry.getAllSessions(principal, true);
        for (SessionInformation sessionInformation : sessionInformations) {
          sessionIdSet.add(sessionInformation.getSessionId());
        }
      }
      Date now = new Date();
      Date yesterday = new DateTime().minusDays(1).toDate();
      for (UserLogonLog userLogonLog : userLogonLogs) {
        if (userLogonLog.getLogonTime().before(yesterday)) {
          Date logoutTime = new DateTime(userLogonLog.getLogonTime()).plusHours(1).toDate();
          userLogonLog.setLogoutTime(logoutTime);
        } else {
          if (sessionIdSet.contains(userLogonLog.getHttpSessionId())) {
            userLogonLog.setLogoutTime(now);
          } else {
            continue;
          }
        }
        logger.debug(" - Setup logout time for session ID: {}", userLogonLog.getHttpSessionId());
        userLogonLog.setLogonTimeLength(
            userLogonLog.getLogoutTime().getTime() - userLogonLog.getLogonTime().getTime());
        userLogonLogService.save(userLogonLog);
      }
    }
  }
  /**
   * Allows subclasses to customise behaviour when too many sessions are detected.
   *
   * @param request
   * @param sessions either <code>null</code> or all unexpired sessions associated with the
   *     principal
   * @param allowableSessions the number of concurrent sessions the user is allowed to have
   * @param registry an instance of the <code>SessionRegistry</code> for subclass use
   */
  protected void allowableSessionsExceeded(
      HttpServletRequest request,
      List<SessionInformation> sessions,
      int allowableSessions,
      SessionRegistry registry)
      throws SessionAuthenticationException {
    String logoutLeastRecentlyUsed = request.getParameter(LOGOUT_LEAST_RECENTLY_USED);

    if (logoutLeastRecentlyUsed == null) {
      throw new SessionAuthenticationConfirmationException(
          messages.getMessage(
              "ConcurrentSessionControlAuthenticationStrategy.exceededAllowed",
              new Object[] {Integer.valueOf(allowableSessions)},
              "Maximum sessions of {0} for this principal exceeded"));
    } else {
      exceptionIfMaximumExceeded = (Boolean.parseBoolean(logoutLeastRecentlyUsed)) ? false : true;
    }

    // ----- original code
    if (exceptionIfMaximumExceeded || (sessions == null)) {
      throw new SessionAuthenticationException(
          messages.getMessage(
              "ConcurrentSessionControlAuthenticationStrategy.exceededAllowed",
              new Object[] {Integer.valueOf(allowableSessions)},
              "Maximum sessions of {0} for this principal exceeded"));
    }

    // Determine least recently used session, and mark it for invalidation
    SessionInformation leastRecentlyUsed = null;

    for (SessionInformation session : sessions) {
      if ((leastRecentlyUsed == null)
          || session.getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
        leastRecentlyUsed = session;
      }
    }

    leastRecentlyUsed.expireNow();
  }
  /**
   * In addition to the steps from the superclass, the sessionRegistry will be updated with the new
   * session information.
   */
  public void onAuthentication(
      Authentication authentication, HttpServletRequest request, HttpServletResponse response) {

    final List<SessionInformation> sessions =
        sessionRegistry.getAllSessions(authentication.getPrincipal(), false);

    int sessionCount = sessions.size();
    int allowedSessions = getMaximumSessionsForThisUser(authentication);

    if (sessionCount < allowedSessions) {
      // They haven't got too many login sessions running at present
      return;
    }

    if (allowedSessions == -1) {
      // We permit unlimited logins
      return;
    }

    if (sessionCount == allowedSessions) {
      HttpSession session = request.getSession(false);

      if (session != null) {
        // Only permit it though if this request is associated with one of the
        // already registered sessions
        for (SessionInformation si : sessions) {
          if (si.getSessionId().equals(session.getId())) {
            return;
          }
        }
      }
      // If the session is null, a new one will be created by the parent class,
      // exceeding the allowed number
    }

    allowableSessionsExceeded(request, sessions, allowedSessions, sessionRegistry);
  }