shiro 实现记住我功能的 rememberMe 功能使用指导为什么rememberMe设置了没作用

shiro(24)
Shiro提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下:
1、首先在登录页面选中RememberMe然后登录成功;如果是浏览器登录,一般会把RememberMe的Cookie写到客户端并保存下来;
2、关闭浏览器再重新打开;会发现浏览器还是记住你的;
3、访问一般的网页服务器端还是知道你是谁,且能正常访问;
4、但是比如我们访问淘宝时,如果要查看我的订单或进行支付时,此时还是需要再进行身份认证的,以确保当前用户还是你。
RememberMe配置
spring-shiro-web.xml配置:
id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"&
value="sid"/&
name="httpOnly" value="true"/&
name="maxAge" value="-1"/&
id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"&
value="rememberMe"/&
name="httpOnly" value="true"/&
name="maxAge" value="2592000"/&
sessionIdCookie:maxAge=-1表示浏览器关闭时失效此Cookie;
rememberMeCookie:即记住我的Cookie,保存时长30天;
id="rememberMeManager"
class="org.apache.shiro.web.mgt.CookieRememberMeManager"&
name="cipherKey" value="
#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/&
name="cookie" ref="rememberMeCookie"/&
rememberMe管理器,cipherKey是加密rememberMe Cookie的密钥;默认AES算法;
id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"&
name="rememberMeManager" ref="rememberMeManager"/&
设置securityManager安全管理器的rememberMeManager;
id="formAuthenticationFilter"
class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"&
name="rememberMeParam" value="rememberMe"/&
rememberMeParam,即rememberMe请求参数名,请求参数是boolean类型,true表示rememberMe。
id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"&
name="filterChainDefinitions"&
/login.jsp = authc
/logout = logout
/authenticated.jsp = authc
/** = user
“/authenticated.jsp = authc”表示访问该地址用户必须身份验证通过(Subject. isAuthenticated()==true);而“/** = user”表示访问该地址的用户是身份验证通过或RememberMe登录的都可以。
1、访问,会跳转到登录页面,登录成功后会设置会话及rememberMe Cookie;
2、关闭浏览器,此时会话cookie将失效;
3、然后重新打开浏览器访问,还是可以访问的;
4、如果此时访问,会跳转到登录页面重新进行身份验证。
如果要自己做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使用过程中,需要配合相应的拦截器来实现相应的功能,用错了拦截器可能就不能满足你的需求了。
示例源代码:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:36777次
积分:1861
积分:1861
排名:第16000名
原创:140篇
(1)(3)(38)(18)(2)(90)Shiro(5)
记住我(RememberMe)的功能
Shiro 提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下:
- 1、首先在登录页面选中RememberMe 然后登录成功;如果是浏览器登录,一般会把RememberMe的Cookie 写到客户端并保存下来;
- 2、关闭浏览器再重新打开;会发现浏览器还是记住你的;
- 3、访问一般的网页服务器端还是知道你是谁,且能正常访问;
- 4、但是比如我们访问淘宝时,如果要查看我的订单或进行支付时,此时还是需要再进行身份认证的,以确保当前用户还是你.
配置基于Form表单的身份验证过滤器
&bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"&
&property name="usernameParam" value="username" /&
&property name="passwordParam" value="password" /&
&property name="rememberMeParam" value="rememberMe" /&
&property name="loginUrl" value="/api/user/login" /&
拦截器配置
/** = user
使用shiro默认的user拦截器。该拦截器要求用户已经登录或者勾选了RememberMe,就可以放行。
shiro设置rememberMe
用firefox浏览器可以看出,shiro在返回响应的时候,首先删除了之前的rememberMe的cookie,然后重新在客户端设置了rememberMe的cookie。
cookie详细信息,shiro默认设置有效期为1年
用户再次访问时,浏览器会发送这个rememberMe的cookie给服务端,无需再登录即可访问
源码托管在;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:77328次
积分:2547
积分:2547
排名:第10940名
原创:173篇
转载:15篇
评论:37条
(1)(2)(3)(5)(5)(5)(4)(6)(4)(4)(15)(4)(6)(7)(17)(7)(13)(4)(21)(55)(3)(1)Coding & Bioinformatics
This site is used to record and share the informations & useful tips during the coding and research.
    Apache Shiro 是一个框架,可用于身份验证和授权。虽然这两个术语代表的是不同的含义,但出于它们在应用程序安全性方面各自的角色考虑,它们有时会被交换使用。
身份验证 指的是验证用户的身份。在验证用户身份时,需要确认用户的身份的确如他们所声称的那样。在大多数应用程序中,身份验证是通过用户名和密码的组合完成的。只要用户选择了他人很难猜到的密码,那么用户名和密码的组合通常就足以确立身份。但是,还有其他的身份验证方式可用,比如指纹、证书和生成键。
    一旦身份验证过程成功地建立起身份,授权 就会接管以便进行访问的限制或允许。 所以,有这样的可能性:用户虽然通过了身份验证可以登录到一个系统,但是未经过授权,不准做任何事情。还有一种可能是用户虽然具有了某种程度的授权,却并未经过身份验证。
在为应用程序规划安全性模型时,必须处理好这两个元素以确保系统具有足够的安全性。身份验证是应用程序常见的问题(特别是在只有用户和密码组合的情况下),所以让框架来处理这项工作是一个很好的做法。合理的框架可提供经过测试和维护的优势,让您可以集中精力处理业务问题,而不是解决其解决方案已经实现的问题。
    Apache Shiro 提供了一个可用的安全性框架,各种客户机都可将这个框架应用于它们的应用程序。本文中的这些例子旨在介绍 Shiro 并着重展示对用户进行身份验证的基本任务。
本文只针对Jeesite中shiro的用法进行整理,不会包括shiro环境配置和搭建等内容。
Jeesite中的shiro
2.1 spring-context-shiro.xml
    spring-context-shiro.xml是shiro的主配置文件,配置信息是重点主要是安全认证过滤器的配置。它规定哪些url需要进行哪些方面的认证和过滤
&!-- 安全认证过滤器 --&
&bean id=&shiroFilter& class=&org.apache.shiro.spring.web.ShiroFilterFactoryBean&&
&property name=&securityManager& ref=&securityManager& /&
&property name=&p& value=&${adminPath}/login& /&
&property name=&successUrl& value=&${adminPath}& /&
&property name=&filters&&
&entry key=&authc& value-ref=&formAuthenticationFilter&/&
&/property&
&property name=&filterChainDefinitions&&
/static/** = anon
/userfiles/** = anon
${adminPath}/login = authc
${adminPath}/logout = logout
${adminPath}/** = user
&/property&
    shiroFilter是shiro的安全认证过滤器,其中,
securityManager:指定一个负责管理的bean,这个新的bean在接下来会定义,其中包含了认证的主要逻辑。
loginUrl:没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。
successUrl:登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。
unauthorizedUrl:没有权限默认跳转的页面。
map中的entry指定了authc权限所对应的过滤器实体
而属性中的filterChainDefinitions则详细规定啦不同的url的对应权限
anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
roles:例子/admins/user/=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/=roles[&admin,guest&],每个参数通过才算通过,相当于hasAllRoles()方法。
perms:例子/admins/user/**=perms[user:add:],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/=perms[&user:add:,user:modify:*&],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
rest:例子/admins/user/=rest[user],根据请求的方法,相当于/admins/user/=perms[user:method] ,其中method为post,get,delete等。
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
注:anon,authcBasic,auchc,user是认证过滤器,perms,roles,ssl,rest,port是授权过滤器
&!-- 定义 Shiro 主要业务对象 --&
&bean id=&securityManager&
class=&org.apache.shiro.web.mgt.DefaultWebSecurityManager&&
&!-- &property name=&sessionManager& ref=&sessionManager& /& --&
&property name=&realm& ref=&systemAuthorizingRealm& /&
&property name=&cacheManager& ref=&shiroCacheManager& /&
    这部分代码定义了securitymanager的主要属性的实体,systemAuthorizingRealm和shiroCacheManager都是自己实现的,分别用于进行验证管理和cache管理。从配置文件能看出,配置文件指定了作为安全逻辑的几个结构,除了这两部分,还包括formAuthenticationFilter。其中realm和filter在com.thinkgem.jeesite.modules.sys.security包里实现。
2.2 FormAuthenticationFilter
    从可见都逻辑上讲,FormAuthenticationFilter类是用户验证时所接触的第一个类。
    当用户登录任意界面时,shiro会对当前状态进行检查。如果发现需要登录,则会自动跳转到配置文件里loginUrl属性所指定的url中。
    而这一url又被指定为authc权限,即需要验证。接着,authc的filter被指定为formAuthenticationFilter,因此login页面所提交的信息被改filter截获进行处理。
    其中的核心逻辑是createToken函数:
protected AuthenticationToken createToken(S2ervletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
if (password==null){
password = &&;
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
String captcha = getCaptcha(request);
return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha);
    UsernamePasswordToken是security包里的第四个类,它继承自shiro的同名类,用于shiro处理中的参数传递。createtoken函数接受到login网页所接受的表单,生成一个token传给下一个类处理。
    函数中的rememberme以及captcha分别表示的是记住用户功能和验证码功能,这部分也是shiro自身携带,我们并不需要修改。filter是通过aop的方式结合到系统里的,因此并没有具体的接口实现。
2.3 SystemAuthorizingRealm
    shiro的最终处理都将交给Real进行处理。因为在Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的。通常情况下,在Realm中会直接从我们的数据源中获取Shiro需要的验证信息。可以说,Realm是专用于安全框架的DAO.
Realm中有个参数是systemService,这个便是spring的具体业务逻辑,其中也包含了具体的DAO,正是在这个部分,shiro与spring的接口具体的结合了起来。
realm当中有两个函数特别重要,分别是用户认证函数和授权函数。
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcT
if (LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
// 判断验证码
Session session = SecurityUtils.getSubject().getSession();
String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
throw new CaptchaException(&验证码错误.&);
User user = getSystemService().getUserByLoginName(token.getUsername());
if (user != null) {
byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
return new SimpleAuthenticationInfo(new Principal(user),
user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
    以上便是用户认证函数,中间关于验证码检测的部分我们暂且不表,其最核心的语句是
User user = getSystemService().getUserByLoginName(token.getUsername());
以及另一句语句
return new SimpleAuthenticationInfo(new Principal(user), user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
    函数的参数AuthenticationToken便是filter所截获并生成的token实例,其内容是login表单里的内容,通常是用户名和密码。在前一句话里,getSystemService取到了systemService实例,该实例中又含有配置好的userDAO,能够直接与数据库交互。因此将用户id传入,取出数据库里所存有的user实例,接着在SimpleAuthenticationInfo生成过程中分别以user实例的用户名密码,以及token里的用户名密码做为参数,验证密码是否相同,以达到验证的目的。
    doGetAuthorizationInfo函数是授权的函数,其具体的权限是在实现类中以annotation的形式指派的,它负责验证用户是否有权限访问。详细的细节容我之后添加。
2.3 LoginController
     LoginController是本该实现登录认证的部分。由于shiro的引入和AOP的使用,jeesite中的LoginController只处理验证之后的部分。
如果通过验证,系统中存在user实例,则返回对应的主页。否则重新定位于login页面。
2.4 annotation
    常用的annotation主要如下:
@RequiresAuthentication
    要求当前Subject 已经在当前的session 中被验证通过才能被注解的类/实例/方法访问或调用。
    验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时。
@RequiresUser
    需要当前的Subject 是一个应用程序用户才能被注解的类/实例/方法访问或调用。要么是通过验证被确认,或者在之前session 中的'RememberMe'服务被记住。
    验证用户是否被记忆,user有两种含义:一种是成功登录的(subject.isAuthenticated() 结果为true);另外一种是被记忆的(subject.isRemembered()结果为true)。
@RequiresGuest
    要求当前的Subject 是一个“guest”,也就是他们必须是在之前的session中没有被验证或记住才能被注解的类/实例/方法访问或调用。
    验证是否是一个guest的请求,与@RequiresUser完全相反。
    换言之,RequiresUser
== !RequiresGuest。此时subject.getPrincipal() 结果为null.
@RequiresRoles
    要求当前的Subject 拥有所有指定的角色。如果他们没有,则该方法将不会被执行,而且AuthorizationException 异常将会被抛出。例如:@RequiresRoles(&administrator&)
或者@RequiresRoles(&aRoleName&);
void someMethod();
    如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。
@RequiresPermissions
    要求当前的Subject 被允许一个或多个权限,以便执行注解的方法,比如:
    @RequiresPermissions(&account:create&)
    或者@RequiresPermissions({&file:read&, &write:aFile.txt&} )
    void someMethod();
3.相关网页
    有一个简易的整体流程实现
http://blog.csdn.net/clj/article/details/
    对授权部分解释较为详细
/forum/posts/list/7456.html
添加新评论
加载中……500 - 内部服务器错误。
500 - 内部服务器错误。
您查找的资源存在问题,因而无法显示。

我要回帖

更多关于 shiro isrememberme 的文章

 

随机推荐