天天看點

Shiro單使用者登入,清理之前登入的使用者

/**
*   new SimpleAuthenticationInfo(user, pwd, this.getName())中的第一個參數是SysUser對象,
*   在其他接收的地方也要轉成SysUser對象,使用對象這裡對應的處理方式是采用方法一,
*   如果是傳遞的userName字元串,則采用方法二進行處理
*/
SimpleAuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user, pwd, this.getName());            

方法一

/**
 * @功能描述:   單使用者登入,清除目前使用者以前登入時儲存的session會話
 * @param loginName
 */
public void singleUseLogin(String loginName){
    // 1.擷取目前使用者sessionId
    String currentUserSessionId = SecurityUtils.getSubject().getSession().getId().toString();

    // 2.擷取shiro的sessionManager
    DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
    DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();

    // 3.擷取所有已登入使用者的session清單
    Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();

    if (sessions.size() > 1) {
        System.out.println("僅允許單使用者登入,開始清理遺留使用者資訊~");
        User user = null;
        for(Session onlineSession:sessions){
            // 4. 擷取已登入使用者的session的key值
            SimplePrincipalCollection simplePrincipalCollection = (SimplePrincipalCollection) onlineSession.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (null == simplePrincipalCollection) {
                sessionManager.getSessionDAO().delete(onlineSession);
                continue;
            }
            // 5. 擷取new SimpleAuthenticationInfo(user, pwd, this.getName())中放進去的第一個參數
            user = (User) simplePrincipalCollection.getPrimaryPrincipal();

            // 6. 清除目前使用者以前登入時儲存的session會話
            if (loginName.equals(user.getUserName()) && !onlineSession.getId().equals(currentUserSessionId)) {
                sessionManager.getSessionDAO().delete(onlineSession);
                System.out.println("清理使用者["+loginName+"],SessionId為["+onlineSession.getId()+"]的Session資訊!");
            }
        }
    } else {
        System.out.println("無可清理使用者資訊~");
    }
}           

方法二

/**
 * @功能描述:   單使用者登入,清除目前使用者以前登入時儲存的session會話
 * @param loginName
 */
public void singleUseLogin(HttpServletRequest request,String loginName){
    // 1.擷取目前使用者sessionId
    String currentUserSessionId = request.getSession().getId();

    // 2.擷取shiro的sessionManager
    DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
    DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();

    // 3.擷取所有已登入使用者的session清單
    Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();

    // 處理方法一:UserRalm中傳入的是userName使用此方法
    String onlineSessionKey = "";
    for(Session onlineSession:sessions){
        // 4.擷取已登入使用者的session的key值
        onlineSessionKey = String.valueOf(onlineSession.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY));
        // 5.清除目前使用者以前登入時儲存的session會話
        System.out.println(onlineSession.getId()+"------" + onlineSessionKey);

        if (onlineSessionKey.equals("null")) {
            sessionManager.getSessionDAO().delete(onlineSession);
        } else if (loginName.equals(onlineSessionKey) && !onlineSession.getId().equals(currentUserSessionId)) {
            sessionManager.getSessionDAO().delete(onlineSession);
        }
    }
}