1. 程式人生 > >Apache Shiro(七)——Shiro的RememberMe功能

Apache Shiro(七)——Shiro的RememberMe功能

一、概述

Shiro 提供了記住我(RememberMe)的功能,比如訪問如淘寶等一些網站時,關閉了瀏覽器,下次再開啟時還是能記住你是誰,下次訪問時無需再登入即可訪問,基本流程如下:

1、首先在登入頁面選中 RememberMe 然後登入成功;如果是瀏覽器登入,一般會把 RememberMe 的Cookie 寫到客戶端並儲存下來
2、關閉瀏覽器再重新開啟;會發現瀏覽器還是記住你的;
3、訪問一般的網頁伺服器端還是知道你是誰,且能正常訪問;
4、但是比如我們訪問淘寶時,如果要檢視我的訂單或進行支付時,此時還是需要再進行身份認證的,以確保當前使用者還是你

二、認證和記住我

subject.isAuthenticated() 表示使用者進行了身份驗證登入的,即使用 Subject.login 進行了登入;

subject.isRemembered():表示使用者是通過記住我登入的,此時可能並不是真正的你(如你的朋友使用你的電腦,或者你的cookie 被竊取)在訪問的;

兩者二選一,即 subject.isAuthenticated()==true,則subject.isRemembered()==false;反之一樣。

三、建議

訪問一般網頁:如個人在主頁之類的,我們使用user 攔截器即可,user 攔截器只要使用者登入(isRemembered() || isAuthenticated())過即可訪問成功;

訪問特殊網頁:如我的訂單,提交訂單頁面,我們使用authc 攔截器即可,authc 攔截器會判斷使用者是否是通過Subject.login(isAuthenticated()==true)登入的,如果是才放行,否則會跳轉到登入頁面叫你重新登入。

四、實現

配置

    /**
     * rememberMe管理器, cipherKey生成見{@code Base64Test.java}
     */
    @Bean
    public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) {
        CookieRememberMeManager manager = new CookieRememberMeManager();
        manager.setCipherKey(Base64.decode("Z3VucwAAAAAAAAAAAAAAAA=="));
        manager.setCookie(rememberMeCookie);
        return manager;
    }
    
    /**
     * 記住密碼Cookie
     */
    @Bean
    public SimpleCookie rememberMeCookie() {
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        simpleCookie.setHttpOnly(true);
        simpleCookie.setMaxAge(7 * 24 * 60 * 60);//7天
        return simpleCookie;
    }

將rememberMeManager 注入到securityManager

/**
     * 安全管理器securityManager
     */
    @Bean
    public DefaultWebSecurityManager securityManager(CookieRememberMeManager rememberMeManager,
                                                     CacheManager cacheShiroManager,
                                                     SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(this.shiroRealm());
        securityManager.setCacheManager(cacheShiroManager);
//        將rememberMeManager 注入到securityManager
        securityManager.setRememberMeManager(rememberMeManager);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }

RememeberMe

如果要自己做RememeberMe,需要在登入之前這樣建立Token:UsernamePasswordToken(使用者名稱,密碼,是否記住我),且呼叫UsernamePasswordToken 的:token.setRememberMe(true) 方法。

 		Subject currentUser = ShiroKit.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray());

        if ("on".equals(remember)) {
            token.setRememberMe(true);
        } else {
            token.setRememberMe(false);
        }

        currentUser.login(token);