Shiro 集成 Spring 之記住我

我們經常在登陸網站時看到一個選項,就是 記住我n天內自動登陸。本章我們使用 Shiro 來實現這個功能。

首先需要在 spring-shiro.xml 中配置:

<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
    <property name="cookie" ref="cookie"/>
</bean>

<bean id="cookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <!-- cookie 名稱 -->
    <property name="name" value="rememberMe"/>
    <!-- cookie 過期時間 -->
    <property name="maxAge" value="86400"/>
</bean>

並將 rememberMeManager 添加到 securityManager中:

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
    <property name="rememberMeManager" ref="rememberMeManager"/>
</bean>

在之前的章節中我們提到了過濾器鏈中的 user 過濾器,以及註解中的 @RequiresUser 都是用來表示已登陸或 rememberMe 狀態可訪問。

我們新建一個頁面 remember.jsp,併爲其配置 user 過濾器:

remember.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>記住我</title>
</head>
<body>
    RememberMe Page
</body>
</html>

過濾器

/remember.jsp = user

當然,還要通過表單的單選框來告訴 Shiro,當前用戶是否使用 rememberMe 功能,修改後的login.jsp

<html>
<body>
<form action="login" method="post">
    username : <input type="text" name="username">
    <br>
    password : <input type="password" name="password">
    <br>
    rememberMe: <input type="checkbox" name="rememberMe">
    <br>
    <input type="submit" value="Login">
</form>
</body>
</html>

並在 Controller 層接受後,將複選框選中結果配置給 Shiro:

@RequestMapping("login")
@ResponseBody
public String login(User user) {
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token =
        new UsernamePasswordToken(user.getUsername(), user.getPassword(), user.getRememberMe());
    try {
        subject.login(token);
    } catch (AuthenticationException e) {
        return e.getMessage();
    }
    return "login success";
}

一切配置完成後啓動項目,登陸時勾選 rememberMe,然後關閉瀏覽器,重新打開,再訪問 remember.jsp 看是否可以訪問,並對比其他配置 authc 或需要授權的頁面,是否可以訪問。

其實他的原理就是通過 cookie 實現,勾選 remberMe 後登陸成功會給瀏覽器設置一個 cookie,以及其到期時間,請求頁面時驗證該 cookie 的內容是否是服務器頒發的,如果是則通過,不是則跳回登陸頁面。

也可能你配置了 rememberMe 功能但未生效,也沒有報錯,那麼可能是以下兩種原因。

  • 檢查瀏覽器是否禁用了 Cookie
  • 檢查是否使用了註解 @RequiresUser並同時在過濾器鏈中配置了 /** = authc,原因是過濾器鏈的優先級高於 @RequiresUser,在 /** = authc 時,表示所有請求都要認證,所以還沒有到註解的驗證就已經被攔截並跳回到登陸頁面了。

不過 rememberMe 功能要慎用,且過期時間不要設置太久,因爲這樣即使修改密碼後,原先的 cookie 在過期之前還是可以使用的。還有一個問題是,rememberMe 狀態下無法獲取用戶的 Session 信息,從而也會引發其他的問題。

本章代碼地址 : https://github.com/zhaojun1998/Premission-Study/tree/master/Permission-Shiro-11/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章