【Shiro】shiro記住我功能

【Shiro】shiro記住我功能


在登錄後,可以將⽤戶名存在cookie中,下次訪問時,可以先不登錄,就可以識別身份。

在確實需要身份認證時,⽐如購買,⽀付或其他⼀些重要操作時,再要求⽤戶登錄即可,⽤戶體驗好。

由於可以保持⽤戶信息,系統後臺也可以更好的監控、記錄⽤戶⾏爲,積累數據。

”記住我“ 起點在登錄時刻:Subject.login(UsernameAndPasswordToken)
⽽是否確定要“記住我”,由登錄時的token控制開關: token.setRememberMe(true);

Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//如果需要記住我的話,需要在token中設置
token.setRememberMe(true);//shiro默認⽀持”記住我“,只要有此設置則⾃動運作。
subject.login(token);

登錄後效果

在⻚⾯中顯示,cookie中記錄的⽤戶信息

<shiro:user> 當有記住我信息,或已登錄,則顯示標籤體內容
<shiro:principal> 獲取⽤戶信息

注意:⾸⻚的訪問路徑的過濾器 不能是 authc,只能是 user 或 anon

<!-- ⾸⻚ xx.jsp -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
    <body>
        <h2>Hello World! </h2>
        <!-- 重點在此:通過如下shiro標籤顯示 -->
        <shiro:user>
            歡迎您,<shiro:principal/> <a href="#">退出登錄</a>
        </shiro:user>
    </body>
</html>
<!-- 登錄⻚⾯ login.jsp ⾃動填充⽤戶名 -->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <form action="/user/login" method="post">
            <!-- 重點在此:<shiro:principal/> -->
            username:<input type="text" name="username" value="<shiro:principal/>"> <br>
            password:<input type="password" name="password"><br>
            <input type="submit" value="登錄">
        </form>
    </body>
</html>

如果需要做⾃定義Cookie,可以明確定義如下兩個組件:

  • SimpleCookie :封裝cookie的相關屬性,定製cookie寫出邏輯( 詳⻅:addCookieHeader() )
  • CookieRememberMeManager :接受SecurityManager調度,獲取⽤戶信息,加密數據,並調度SimpleCookie寫出cookie
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- shiro配置 -->
    <!-- Realm -->
    <bean id="myRealm" class="com.siyi.realm.MyRealm">
        <property name="userService" ref="userServiceImpl"/>
        <property name="roleService" ref="roleServiceImpl"/>
        <property name="permissionService" ref="permissionServiceImpl"/>
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <property name="hashAlgorithmName" value="SHA-256"/>
                <property name="storedCredentialsHexEncoded" value="false"/>
                <property name="hashIterations" value="10000"/>
            </bean>
        </property>
    </bean>

    <!-- 聲明SecurityManager -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm"/>
        <!-- CookieRememberMeManager注⼊給SecurityManager,
        SecurityManager在處理login時,如果login成功,則會通過rememberMeManager做"記住我",
        將⽤戶名存⼊cookie
        -->
        <property name="rememberMeManager" ref="rememberMeManager"/>
        <!-- 增加配置sessionManager -->
        <property name="sessionManager" ref="sessionManager"/>
    </bean>

    <!-- ⽣產SpringShiroFilter
    ( 持有shiro的過濾相關規則,可進⾏請求的過濾校驗,校驗請求是否合法 )
    -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 注入核心對象 -->
        <property name="securityManager" ref="securityManager"/>
        <!-- 未登錄,沒有權限時的跳轉路徑 -->
        <property name="loginUrl" value="/user/login/page"/>
        <property name="unauthorizedUrl" value="/user/perms/error"/>
        <!-- 過濾器鏈 -->
        <property name="filterChainDefinitions">
            <value>
                /user/query=authc,roles["banzhang"]
                /user/insert=authc,roles["banfu"]
                /user/update=authc,perms[""student:update""]
                /order/insert=authc,roles["xuewei"]
                /user/logout=logout
            </value>
        </property>
    </bean>

    <!-- 記住我Cookie -->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- rememberMe是cookie值中的key,value時⽤戶名的密⽂
        cookie["rememberMe":"deleteMe"] 此cookie每次登陸後都會寫出,⽤於清除之前的cookie
        cookie["rememberMe":username的密⽂] 此cookie也會在登錄後寫出,⽤於記錄最新的username
        (ops: 如上設計,既能保證每次登陸後重新記錄cookie,也能保證切換賬號時,記錄最新賬號)
        -->
        <property name="name" value="rememberMe"/>
        <!-- cookie只在http請求中可⽤,那麼通過js腳本將⽆法讀取到cookie信息,有效防⽌cookie被竊取 -->
        <property name="httpOnly" value="true"/>
        <!-- cookie的⽣命週期,單位:秒 -->
        <property name="maxAge" value="604800"/><!-- 7天 -->
    </bean>

    <!-- 記住我管理器 -->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <!-- 對cookie的value加密的密鑰 建議每個項⽬都不⼀樣
        加密⽅式AES(對稱加密)
        密鑰⽣成:【KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecretKey deskey = keygen.generateKey();
        System.out.println(Base64.encodeToString(deskey.getEncoded()));】
        SpEL:Spring Expression Language #{表達式} #{T(類型)...}
        <property name="cipherKey"
        value="#{T(org.apache.shiro.codec.Base64).decode('c+3hFGPjbgzGdrC+MHgoRQ==')}"/>
        此配置可以省略,CookieRememberMeManager⾃動完成祕鑰⽣成
        -->
        <!-- 注⼊SimpleCookie -->
        <property name="cookie" ref="rememberMeCookie"/>
    </bean>

    <!-- 增加session管理相關配置 -->
    <!-- 會話Cookie模板 默認可省-->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- cookie的 key="sid" -->
        <property name="name" value="JSESSIONID"/>
        <!-- 只允許http請求訪問cookie -->
        <property name="httpOnly" value="true"/>
        <!-- cookie過期時間,-1:存活⼀個會話 ,單位:秒 ,默認爲-1-->
        <property name="maxAge" value="-1"/>
    </bean>

    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- 默認值和配置中給出的⼀致,所bean:sessionIdCookie 可以省略 -->
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
        <!-- session全局超時時間, 單位:毫秒 ,30分鐘 默認值爲1800000-->
        <property name="globalSessionTimeout" value="1800000"/>
    </bean>
</beans>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章