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); }