`
jinnianshilongnian
  • 浏览: 21514097 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2420554
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3010289
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5640622
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:260243
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597966
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250375
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5860629
Group-logo
跟我学Nginx+Lua开...
浏览量:702897
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785763
社区版块
存档分类
最新评论

第十三章 RememberMe——《跟我学Shiro》

阅读更多

 

目录贴: 跟我学Shiro目录贴

 

Shiro提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下:

1、首先在登录页面选中RememberMe然后登录成功;如果是浏览器登录,一般会把RememberMe的Cookie写到客户端并保存下来;

2、关闭浏览器再重新打开;会发现浏览器还是记住你的;

3、访问一般的网页服务器端还是知道你是谁,且能正常访问;

 

4、但是比如我们访问淘宝时,如果要查看我的订单或进行支付时,此时还是需要再进行身份认证的,以确保当前用户还是你。

RememberMe配置

 

spring-shiro-web.xml配置:

<!-- 会话Cookie模板 -->
<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天;

  

<!-- 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算法;

 

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

设置securityManager安全管理器的rememberMeManager; 

 

<bean id="formAuthenticationFilter" 
class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
	……
    <property name="rememberMeParam" value="rememberMe"/>
</bean> 

rememberMeParam,即rememberMe请求参数名,请求参数是boolean类型,true表示rememberMe。 

 

<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(用户名,密码,是否记住我),如:

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使用过程中,需要配合相应的拦截器来实现相应的功能,用错了拦截器可能就不能满足你的需求了。

 

示例源代码:https://github.com/zhangkaitao/shiro-example;可加群 231889722 探讨Spring/Shiro技术。

 

        

26
4
分享到:
评论
21 楼 mms 2017-11-22  
为啥我按照示例配置会出现如下错误:
java.lang.NoSuchFieldException: rememberMe
at java.lang.Class.getField(Class.java:1703)
        at org.springframework.beans.TypeConverterDelegate.attemptToConvertStringToEnum(TypeConverterDelegate.java:316)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:243)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:93)
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:64)
20 楼 xiao明123 2017-04-19  
WARN  [org.apache.shiro.mgt.AbstractRememberMeManager] - There was a failure while trying to retrieve remembered principals.  This could be due to a configuration problem or corrupted principals.  This could also be due to a recently changed encryption key, if you are using a shiro.ini file, this property would be 'securityManager.rememberMeManager.cipherKey' see: http://shiro.apache.org/web.html#Web-RememberMeServices. The remembered identity will be forgotten and not used for this request.
  2017-04-19 13:54:03,488 [qtp763610533-19] WARN  [org.apache.shiro.mgt.DefaultSecurityManager] - Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during getRememberedPrincipals().
  org.apache.shiro.io.SerializationException: Unable to deserialze argument byte array.
at org.apache.shiro.io.DefaultSerializer.deserialize(DefaultSerializer.java:82)
at org.apache.shiro.mgt.AbstractRememberMeManager.deserialize(AbstractRememberMeManager.java:507)

.......

Caused by: java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1379)
at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1682)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1345)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)


这是怎么回事啊 
19 楼 liaqing 2017-04-17  
<!-- 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>  


为什么会报错
Caused by: java.security.InvalidKeyException: Invalid AES key length: 60 bytes
18 楼 flyChan 2017-02-21  
请问cipherKey是不是可以任意修改?还是说需要用什么算法进行生成?
17 楼 纵观全局 2016-09-13  
已经有cookie了 ,也可以登陆其他页面了 。就是直接项目名出404   ,没有登陆的时候是跳转到login页面。现在有cookie了,为啥不能到指定页面
16 楼 yhqnh 2016-07-17  
lovebird321 写道
shenjianhua1984 写道
同一个用户登录多次,每次都会在cookie中带上rememberMe=...  信息,多次登录后,我再用第一次返回的rememberMe信息,还是能访问系统?这个是不是有问题?
另外看shiro的源码,对于rememberMe,服务端只是把PrincipalCollection序列化和反序列化
并没有对反序列化后的凭证信息再次进行验证,就算服务器重启后,用之前的rememberMe信息还是能访问系统。


还麻烦Tao哥答疑下,看是不是我的理解有问题?谢谢!



恩,我这里也有这个问题。不知道有没有什么好的解决方案。



这个问题我也有,我设置remember me为1分钟,把remember cookie保存下来,1分钟后原始页面cookie自动过期删除需要登录才能访问授权页面。
但是我把提前保存的cookie再请求需授权页面则无需登录可以访问,即使我把服务器重启了还是能无需登录访问,说明remember me的cookie maxAge有效期服务端没有判断
15 楼 a623939400 2016-05-18  
开启rememberMe后修改密码,之前的cookie并不会失效。
请问如何解决?
14 楼 aboutyang 2015-11-17  
shenjianhua1984 写道
同一个用户登录多次,每次都会在cookie中带上rememberMe=...  信息,多次登录后,我再用第一次返回的rememberMe信息,还是能访问系统?这个是不是有问题?
另外看shiro的源码,对于rememberMe,服务端只是把PrincipalCollection序列化和反序列化
并没有对反序列化后的凭证信息再次进行验证,就算服务器重启后,用之前的rememberMe信息还是能访问系统。


还麻烦Tao哥答疑下,看是不是我的理解有问题?谢谢!



localhost 使用Set-Cookie无效,测试可以在hosts中配置一个域名
13 楼 Daniel_yexi 2015-09-08  
设置了shiro的rememberMe ,tomcat设置了默认登录项目,我写了一个过滤器是在登录界面之前验证有没有之前做了记住密码操作的。但是tomcat设置默认项目之后尽管我有记住密码但是都是验证不通过,但是打完全名就是把项目名也打上就可以。。求解!
12 楼 lovebird321 2015-08-11  
shenjianhua1984 写道
同一个用户登录多次,每次都会在cookie中带上rememberMe=...  信息,多次登录后,我再用第一次返回的rememberMe信息,还是能访问系统?这个是不是有问题?
另外看shiro的源码,对于rememberMe,服务端只是把PrincipalCollection序列化和反序列化
并没有对反序列化后的凭证信息再次进行验证,就算服务器重启后,用之前的rememberMe信息还是能访问系统。


还麻烦Tao哥答疑下,看是不是我的理解有问题?谢谢!



恩,我这里也有这个问题。不知道有没有什么好的解决方案。
11 楼 shenjianhua1984 2015-07-09  
同一个用户登录多次,每次都会在cookie中带上rememberMe=...  信息,多次登录后,我再用第一次返回的rememberMe信息,还是能访问系统?这个是不是有问题?
另外看shiro的源码,对于rememberMe,服务端只是把PrincipalCollection序列化和反序列化
并没有对反序列化后的凭证信息再次进行验证,就算服务器重启后,用之前的rememberMe信息还是能访问系统。


还麻烦Tao哥答疑下,看是不是我的理解有问题?谢谢!

10 楼 天明破晓 2015-06-27  
天明破晓 写道
楼主好,我在测试这个例子的时候,并没有发现rememberMe的cookie,怎么回事呢?

测试没有成功
9 楼 天明破晓 2015-06-27  
楼主好,我在测试这个例子的时候,并没有发现rememberMe的cookie,怎么回事呢?
8 楼 fan7421436 2014-07-14  
UsernamePasswordToken token = null;
if (!subject.isAuthenticated() && subject.isRemembered()) {
Object principal = subject.getPrincipal();
if (null != principal) {
Member mem = (Member) principal;
token = new UsernamePasswordToken(mem.getAccountName(),
mem.getLoginPassword());
token.setRememberMe(true);
subject.login(token);// 登录
}
} else {

               //省略代码-里面是一个新的token 生成
}

-----------------
我看我们同事这样写的,没有在shiro里面配置,也实现了记住我的功能。关闭浏览器重新打开,也做到了
7 楼 fan7421436 2014-07-14  
UsernamePasswordToken token = null;
if (!subject.isAuthenticated() && subject.isRemembered()) {
Object principal = subject.getPrincipal();
if (null != principal) {
Member mem = (Member) principal;
token = new UsernamePasswordToken(mem.getAccountName(),
mem.getLoginPassword());
token.setRememberMe(true);
subject.login(token);// 登录
}
} else {

}
6 楼 z19910509 2014-04-01  
z19910509 写道
涛 哥,我把web.xml 中的ContextLoaderListener和DelegatingFilterProxy都去了,为啥访问各个页面还是自动跳转到登录页面


多次运行jetty:run 难道不是重启服务器吗?看控制台怎么有多个进程,把这些玩意儿都关了重启了一遍,能够看到改变的内容了,难道是这原因?
5 楼 z19910509 2014-04-01  
涛 哥,我把web.xml 中的ContextLoaderListener和DelegatingFilterProxy都去了,为啥访问各个页面还是自动跳转到登录页面
4 楼 Crazyliuxj 2014-03-20  
Crazyliuxj 写道
tao哥,访问http://localhost:8080/chapter13/ 跳转到登陆页面是哪里控制的?有点搞不清楚了

明白了,是shiroFilter的loginUrl控制的。另一个问题,如果shiroFilter和formAuthenticationFilter都设置了successUrl,表单成功登陆后会如何跳转呢?
3 楼 Crazyliuxj 2014-03-20  
tao哥,访问http://localhost:8080/chapter13/ 跳转到登陆页面是哪里控制的?有点搞不清楚了
2 楼 loveli 2014-03-19  
终于有人出shiro的专栏了,官方文档讲的内容有点儿少,没多少示例。spring security和shiro,单都是停留在会使用的层面。继续关注您的专栏,期待后面的文章……

相关推荐

    跟我学Shiro第13章Demo(RememberMe)

    "跟我学Shiro第13章Demo(RememberMe)"是一个实战教程,旨在帮助开发者理解并实现Shiro中的RememberMe特性。RememberMe功能允许用户在一段时间内免于重新登录,提高了用户体验。 在这个Demo中,我们将探讨以下几个...

    第十七章 OAuth2集成——《跟我学Shiro》 - 开涛的博客 - ITeye技术网站2

    在《跟我学Shiro》的第十七章中,作者开涛介绍了如何集成OAuth2,使用Apache Oltu作为OAuth2服务端的实现。实现中涉及以下关键部分: 1. **依赖**:引入了`authzserver`(授权服务器依赖)和`resourceserver`(资源...

    跟我一起学shiro 张开涛

    《跟我一起学Shiro——张开涛》这本书是针对初学者的优秀教程,旨在帮助读者快速理解和掌握Shiro的基本用法和核心概念。 **1. Shiro基础** Shiro的基础概念包括Subject、Realms、Cryptography和Session。Subject是...

    [资料][Java]跟我学Shiro教程_Java跟我学Shiro教程_shiro_

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常方便地开发出足够安全的应用。...阅读 "[资料][Java]跟我学Shiro教程.pdf",你将得到更详细的步骤指导和实践案例。

    《跟我学Shiro》- 张开涛.txt

    ***txt文件中含有下载地址** 《跟我学Shiro》- 张开涛,PDF版本,带目录,清晰。 示例源代码:https://github.com/zhangkaitao/shiro-example; 加qun 231889722 探讨Spring/Shiro技术。

    跟我学Shiro

    通过《跟我学Shiro》.pdf,你将学习到如何创建 Realm 实现数据源连接、配置 Shiro 安全框架、处理登录和登出逻辑、实现权限控制以及在实际项目中部署和调优 Shiro。 10. **最佳实践** 学习 Shiro 的过程中,了解...

    跟我学Shiro教程.rar

    "跟我学Shiro教程"这个资源显然是为了帮助学习者深入理解并掌握Shiro的核心概念和实际应用。 在Shiro的认证服务中,其主要目标是确认用户身份。这通常涉及用户登录过程,其中用户提供的凭证(如用户名和密码)被...

    跟我学Shiro-java开发+spring开发

    《跟我学Shiro-java开发+spring开发》是一个深入学习Java安全框架Shiro和Spring集成的教程,旨在帮助开发者掌握这两个关键技术在实际项目中的应用。Shiro是一个强大的且易用的Java安全框架,提供了认证、授权、加密...

    跟我学shiro

    #### 十三、RememberMe - **概念**:允许用户记住登录状态的功能。 - **配置**:通过配置 RememberMe 功能来实现。 #### 十四、SSL - **概念**:使用 SSL 加密通信,保护数据安全。 #### 十五、单点登录 - **概念*...

    跟我学Shiro教程及其课程分章节源码

    Apache Shiro是一个强大易用的Java安全框架,...我找了一版 跟我学Shiro教程PDF,里面讲的很详细.里面还附带了每个章节的源码.值得你收藏哟!饮水思源——原文出自:http://jinnianshilongnian.iteye.com/blog/2049092

    跟我学Shiro教程 pdf

    《跟我学Shiro》PDF完结版下载, Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...

    shiro教程 跟我学Shiro教程

    "跟我学Shiro教程"资源包包含了全面学习Shiro所需的重要材料,包括文档和实践示例。 首先,我们来看《Apache_Shiro参考手册中文版.pdf》。这本书籍详细介绍了Shiro框架的各个组件和使用方法。通过阅读,你可以了解...

    跟我学Shiro第11章Demo

    在"跟我学Shiro第11章Demo"中,我们将深入探讨Shiro的核心组件,特别是其在缓存管理和会话管理中的应用。 首先,我们关注的是Cache缓存。Shiro支持缓存来提高性能,避免频繁的数据库查询。它允许开发者将敏感操作的...

    跟我学 Shiro - v1.1.rar

    Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Sp ring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所 ...

    跟我学shiro文档及源码

    在《跟我学Shiro》这本书中,作者深入浅出地讲解了 Shiro 的核心概念与实际应用场景,配合源码分析,有助于读者更好地理解和掌握 Shiro 的工作原理。 1. **Shiro 概述** - Shiro 的设计目标是简化应用安全开发,它...

    跟我学shiro源代码

    "跟我学Shiro源代码"是一份针对Shiro框架的详细教程,通过这本书,读者能够深入理解Shiro的核心概念和用法,并通过实际的代码示例来提升自己的技能。 1. **身份验证(Authentication)**:Shiro提供了一套完善的...

Global site tag (gtag.js) - Google Analytics