Shiro 提供了記住我(RememberMe)的功能,比如訪問如淘寶等一些網站時,關閉了瀏覽器下次再打開時還是能記住你是誰,下次訪問時無需再登錄即可訪問,基本流程如下:
1. 首先在登錄頁面選中 RememberMe 然后登錄成功;如果是瀏覽器登錄,一般會把 RememberMe 的 Cookie 寫到客戶端并保存下來;
2. 關閉瀏覽器再重新打開;會發現瀏覽器還是記住你的;
3. 訪問一般的網頁服務器端還是知道你是誰,且能正常訪問;
4. 但是比如我們訪問淘寶時,如果要查看我的訂單或進行支付時,此時還是需要再進行身份認證的,以確保當前用戶還是你。
## 13.1 RememberMe 配置
**spring-shiro-web.xml 配置**:
``` xml
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="-1"/>
</bean>
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="2592000"/><!-- 30天 -->
</bean>
```
* sessionIdCookie:maxAge=-1 表示瀏覽器關閉時失效此 Cookie;
* rememberMeCookie:即記住我的 Cookie,保存時長 30 天;
``` xml
<!-- rememberMe管理器 -->
<bean id="rememberMeManager"
class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cipherKey" value="
\#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/>
<property name="cookie" ref="rememberMeCookie"/>
</bean>
```
rememberMe 管理器,cipherKey 是加密 rememberMe Cookie 的密鑰;默認 AES 算法;
``` xml
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
……
<property name="rememberMeManager" ref="rememberMeManager"/>
</bean>
```
設置 securityManager 安全管理器的 rememberMeManager;
``` xml
<bean id="formAuthenticationFilter"
class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
……
<property name="rememberMeParam" value="rememberMe"/>
</bean>
```
rememberMeParam,即 rememberMe 請求參數名,請求參數是 boolean 類型,true 表示 rememberMe。
``` xml
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
……
<property name="filterChainDefinitions">
<value>
/login.jsp = authc
/logout = logout
/authenticated.jsp = authc
/** = user
</value>
</property>
</bean>
```
“/authenticated.jsp = authc” 表示訪問該地址用戶必須身份驗證通過(Subject. isAuthenticated()==true);而 “/\*\* = user” 表示訪問該地址的用戶是身份驗證通過或 RememberMe 登錄的都可以。
**測試**:
1. 訪問 `http://localhost:8080/chapter13/`,會跳轉到登錄頁面,登錄成功后會設置會話及 rememberMe Cookie;
2. 關閉瀏覽器,此時會話 cookie 將失效;
3. 然后重新打開瀏覽器訪問 `http://localhost:8080/chapter13/`,還是可以訪問的;
4. 如果此時訪問 `http://localhost:8080/chapter13/authenticated.jsp`,會跳轉到登錄頁面重新進行身份驗證。
如果要自己做 RememeberMe,需要在登錄之前這樣創建 Token:UsernamePasswordToken(用戶名,密碼,是否記住我),如:
``` java
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(true);
subject.login(token);
```
subject.isAuthenticated() 表示用戶進行了身份驗證登錄的,即使有 Subject.login 進行了登錄; subject.isRemembered():表示用戶是通過記住我登錄的,此時可能并不是真正的你(如你的朋友使用你的電腦,或者你的 cookie 被竊取)在訪問的;且兩者二選一,即 subject.isAuthenticated()==true,則 subject.isRemembered()==false;反之一樣。
另外對于過濾器,一般這樣使用:
**訪問一般網頁**,如個人在主頁之類的,我們使用 user 攔截器即可,user 攔截器只要用戶登錄 (isRemembered()==true or isAuthenticated()==true) 過即可訪問成功;
**訪問特殊網頁**,如我的訂單,提交訂單頁面,我們使用 authc 攔截器即可,authc 攔截器會判斷用戶是否是通過 Subject.login(isAuthenticated()==true)登錄的,如果是才放行,否則會跳轉到登錄頁面叫你重新登錄。
因此 RememberMe 使用過程中,需要配合相應的攔截器來實現相應的功能,用錯了攔截器可能就不能滿足你的需求了。
- 第1章 Shiro簡介
- 1.1 簡介
- 第2章 身份驗證
- 第3章 授權
- 第4章 INI配置
- 第5章 編碼 / 加密
- 第6章 Realm及相關對象
- 第7章 與Web集成
- 第8章 攔截器機制
- 第9章 JSP標簽
- 第10章 會話管理
- 第11章 緩存機制
- 第12章 與Spring集成
- 第13章 RememberMe
- 第14章 SSL
- 第15章 單點登錄
- 第16章 綜合實例
- 第17章 OAuth2集成
- 第18章 并發登錄人數控制
- 第19章 動態URL權限控制
- 第20章 無狀態Web應用集成
- 第21章 授予身份及切換身份
- 第22章 集成驗證碼
- 第23章 多項目集中權限管理及分布式會話
- 第24章 在線會話管理