shiro - rememberMe

applicationContext-shiro.xml

我这里只列出rememberMe需要添加的部分,详细的,最下面有。

 

    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <property name="name" value="rememberMe"/>
        <property name="httpOnly" value="true"/>
        <property name="maxAge" value="2592000"/>
    </bean>

    <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>

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

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">   
        <property name="filterChainDefinitions">
            <value>
                /test2.jsp = user
            </value>
        </property>
    </bean>

maxAge设置了30天,也就是说,在30天之内,你成功认证通过了或者选择了RememberMe,直接访问test2.jsp页面,都可以访问成功。因为我对/test2.jsp设置了user,也就是只能认证通过或者记住我,才能访问这个页面。

(我又遇到了时区差八小时的问题。+_+。 )  从19:27分设置的,加30天。结果就是这样。需要考虑时区的问题。

下面是我自己写的controller:

@Controller
@RequestMapping("/v1")
public class UserController {

    @RequestMapping("/login")
    public String login(User user, Model model, HttpServletRequest request) {
        if (user.getUsername() == null) {
            model.addAttribute("error", "账号不能为空");
            return "forward:/login.jsp";
        }
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        Boolean isRemember = Boolean.valueOf(request.getParameter("rememberMe"));
        if (isRemember)
            token.setRememberMe(true);
        try {
            subject.login(token);
        } catch(AuthenticationException e) {
            model.addAttribute("error", "登录失败");
            e.printStackTrace();
            return "forward:/login.jsp";
        }
        if (subject.isAuthenticated() || subject.isRemembered())
            return "loginSuccess";
        return null;
    }
}

这个是我完整的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

    <!--缓存管理器 使用Ehcache实现-->
    <bean id="cacheManager2" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache2.xml"/>
    </bean>

    <!-- Realm实现 -->
    <bean id="userRealm" class="com.mzs.realm.UserRealm">
        <property name="cachingEnabled" value="true"/>
        <property name="authenticationCachingEnabled" value="true"/>
        <property name="authenticationCacheName" value="authenticationCache"/>
        <property name="authorizationCachingEnabled" value="true"/>
        <property name="authorizationCacheName" value="authorizationCache"/>
    </bean>

    <!-- 会话ID生成器 -->
    <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>

    <!-- 会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <property name="name" value="sid"/>
        <property name="httpOnly" value="true"/>
        <!-- cookie的生存时间,单位:秒 -->
        <property name="maxAge" value="-1"/>
    </bean>

    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <property name="name" value="rememberMe"/>
        <property name="httpOnly" value="true"/>
        <property name="maxAge" value="2592000"/>
    </bean>

    <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>

    <!-- 会话DAO -->
    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
        <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>

    <!-- 会话验证调度器 -->
    <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
        <!-- 调度时间间隔,单位:毫秒,默认值:1小时 -->
        <property name="sessionValidationInterval" value="1800000"/>
        <property name="sessionManager" ref="sessionManager"/>
    </bean>

    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- 全局会话超时时间,默认30分钟 -->
        <property name="globalSessionTimeout" value="1800000"/>
        <!-- 删除过期的会话,默认是true -->
        <property name="deleteInvalidSessions" value="true"/>
        <!-- 会话验证调度器是否开启,默认是true -->
        <property name="sessionValidationSchedulerEnabled" value="true"/>
        <!-- 会话验证调度器,默认是ExecutorServiceSessionValidationScheduler -->
        <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
        <!-- 会话缓存 -->
        <property name="sessionDAO" ref="sessionDAO"/>
        <!-- 是否启用创建cookie的模板,默认是true -->
        <property name="sessionIdCookieEnabled" value="true"/>
        <!-- 创建cookie的模板 -->
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realms">
            <list>
                <ref bean="userRealm"/>
            </list>
        </property>
        <property name="sessionManager" ref="sessionManager"/>
        <property name="rememberMeManager" ref="rememberMeManager"/>
    </bean>

    <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
        <property name="arguments" ref="securityManager"/>
    </bean>

    <!-- Shiro的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/login.jsp"/>
        <property name="successUrl" value="/jsp/loginSuccess.jsp"/>
        <property name="unauthorizedUrl" value="/jsp/unauthorized.jsp"/>
        <property name="filterChainDefinitions">
            <value>
                /index.jsp = anon
                /jsp/unauthorized.jsp = anon
                /login.jsp = anon
                /jsp/logout = logout
                /test2.jsp = user
            </value>
        </property>
    </bean>

    <!-- Shiro生命周期处理器-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 开启shiro注解 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>


</beans>

ehcache2.xml: 

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" name="ehcache2">

    <diskStore path="java.io.tmpdir/ehcache"/>

    <defaultCache maxEntriesLocalHeap="10000"
                  eternal="false"
                  timeToIdleSeconds="120"
                  timeToLiveSeconds="120"
                  maxEntriesLocalDisk="10000000"
                  diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU">

    </defaultCache>

    <!-- 登录记录缓存 锁定10分钟 -->
    <cache name="passwordRetryCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authenticationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="shiro-activeSessionCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

</ehcache>

如有疑问,请联系我本人。QQ:2630866203

### Apache Shiro RememberMe 功能实现与使用教程 #### 1. 记住我 (RememberMe) 的基本概念 Shiro 提供了记住我(RememberMe)的功能,允许用户在关闭浏览器后再次访问时仍然保持登录状态。这意味着即使会话过期或浏览器被关闭,用户也不必重新输入凭证来验证身份[^2]。 #### 2. 配置 RememberMe 功能 为了启用此特性,在应用程序配置文件中设置相应的参数: ```properties shiro.rememberMe.cookieName=rememberMeCookie shiro.rememberMe.timeout=2592000 # 单位秒,默认一个月有效期 ``` 这些属性定义了用于存储令牌的 cookie 名称以及其有效期限。 #### 3. 使用代码集成 RememberMe 当创建 `DefaultWebSecurityManager` 或其他类型的 SecurityManager 实例时,可以通过如下方式开启并自定义 RememberMe 支持: ```java import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; // 创建安全管理器实例... DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); // 设置 RememberMe Manager ... securityManager.setRememberMeManager(new CookieRememberMeManager()); // 将安全管理者应用到当前环境上下文中... SecurityUtils.setSecurityManager(securityManager); ``` 对于 Web 应用程序而言,通常会在 web.xml 中声明过滤器链以便处理 HTTP 请求中的认证逻辑: ```xml <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.apache.shiro.spring.web.ShiroFilterFactoryBean</filter-class> <!-- ... --> <init-param> <param-name>loginUrl</param-name> <param-value>/login.jsp</param-value> </init-param> <init-param> <param-name>successUrl</param-name> <param-value>/index.jsp</param-value> </init-param> <init-param> <param-name>unauthorizedUrl</param-name> <param-value>/error/401.html</param-value> </init-param> <init-param> <param-name>filters</param-name> <param-value>authc,roles,ssl,user,anon,logout,**rememberMe**</param-value> </init-param> </filter> ``` 注意这里的 **rememberMe** 过滤器名称,它负责解析来自客户端请求头里的 rememberMe token 并尝试恢复用户的主体信息。 #### 4. 安全注意事项 由于存在潜在的安全风险,建议采取措施保护系统的安全性: - 不要使用默认密钥; - 对敏感操作实施额外的身份验证检查; - 缩短 rememberMe cookies 的生命周期; - 启用 HTTPS 来防止中间人攻击获取未密传输的数据流。 通过上述步骤可以有效地利用 Apache ShiroRememberMe 特性提升用户体验的同时保障系统安全[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值