`

第十三章 RememberMe

 
阅读更多

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

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

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

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

 

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

RememberMe配置

 

spring-shiro-web.xml配置:

Java代码  收藏代码
  1. <!-- 会话Cookie模板 -->  
  2. <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
  3.     <constructor-arg value="sid"/>  
  4.     <property name="httpOnly" value="true"/>  
  5.     <property name="maxAge" value="-1"/>  
  6. </bean>  
  7. <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
  8.     <constructor-arg value="rememberMe"/>  
  9.     <property name="httpOnly" value="true"/>  
  10.     <property name="maxAge" value="2592000"/><!-- 30天 -->  
  11. </bean>   

sessionIdCookie:maxAge=-1表示浏览器关闭时失效此Cookie;

rememberMeCookie:即记住我的Cookie,保存时长30天;

  

Java代码  收藏代码
  1. <!-- rememberMe管理器 -->  
  2. <bean id="rememberMeManager"   
  3. class="org.apache.shiro.web.mgt.CookieRememberMeManager">  
  4.     <property name="cipherKey" value="  
  5. #{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/>  
  6.      <property name="cookie" ref="rememberMeCookie"/>  
  7. </bean>   

rememberMe管理器,cipherKey是加密rememberMe Cookie的密钥;默认AES算法;

 

Java代码  收藏代码
  1. <!-- 安全管理器 -->  
  2. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  3. ……  
  4.     <property name="rememberMeManager" ref="rememberMeManager"/>  
  5. </bean>   

设置securityManager安全管理器的rememberMeManager; 

 

Java代码  收藏代码
  1. <bean id="formAuthenticationFilter"   
  2. class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">  
  3.     ……  
  4.     <property name="rememberMeParam" value="rememberMe"/>  
  5. </bean>   

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

 

Java代码  收藏代码
  1. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  2.     ……  
  3.     <property name="filterChainDefinitions">  
  4.         <value>  
  5.             /login.jsp = authc  
  6.             /logout = logout  
  7.             /authenticated.jsp = authc  
  8.             /** = user  
  9.         </value>  
  10.     </property>  
  11. </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(用户名,密码,是否记住我),如:

Java代码  收藏代码
  1. Subject subject = SecurityUtils.getSubject();  
  2. UsernamePasswordToken token = new UsernamePasswordToken(username, password);  
  3. token.setRememberMe(true);  
  4. 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使用过程中,需要配合相应的拦截器来实现相应的功能,用错了拦截器可能就不能满足你的需求了。

 

RememberMe原理解析

选择rememberMe之后,shiro会生成一个rememberme的cookie在浏览器中.而且这个参数会随着你调用 subject.logout() 会被自动清除。这个参数的值是一串很长的Base64加密过的字符串,大概长这样

这串字符串其实是对你登陆后的 Principal 进行了序列化后再Base64的结果。Principal 是 shiro 的一个概念,表示一个唯一的字符串能表示你这个用户的,如果你按照最简单的用户名密码登陆的方式,并且使用的是 SimpleAuthenticationInfo 对象,那么这个 Principal 其实就是一个字符串,就是你的用户名 username.

每次访问的时候在DefaultSecurityManager代码中

 

public Subject createSubject(SubjectContext subjectContext) {
        //create a copy so we don't modify the argument's backing map:
        SubjectContext context = copy(subjectContext);

        //ensure that the context has a SecurityManager instance, and if not, add one:
        context = ensureSecurityManager(context);

        //Resolve an associated Session (usually based on a referenced session ID), and place it in the context before
        //sending to the SubjectFactory.  The SubjectFactory should not need to know how to acquire sessions as the
        //process is often environment specific - better to shield the SF from these details:
        context = resolveSession(context);

        //Similarly, the SubjectFactory should not require any concept of RememberMe - translate that here first
        //if possible before handing off to the SubjectFactory:
        context = resolvePrincipals(context);

        Subject subject = doCreateSubject(context);

        //save this subject for future reference if necessary:
        //(this is needed here in case rememberMe principals were resolved and they need to be stored in the
        //session, so we don't constantly rehydrate the rememberMe PrincipalCollection on every operation).
        //Added in 1.2:
        save(subject);

        return subject;
    }
  context = resolvePrincipals(context);会去读取rememberme的cookie值,转换成Principal保存在context中,
  Subject subject = doCreateSubject(context);会创建subject 绑定在当前线程中。
 在userFilter拦截器中
  
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (isLoginRequest(request, response)) {
            return true;
        } else {
            Subject subject = getSubject(request, response);
            // If principal is not null, then the user is known and should be allowed access.
            return subject.getPrincipal() != null;
        }
    }
   protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        saveRequestAndRedirectToLogin(request, response);
        return false;
    }
 
 Subject subject = getSubject(request, response);会去获取绑定线程中的subject,发现Principals存在.就不会去走onAccessDenied方法.

 

 

 

 

分享到:
评论

相关推荐

    跟我学Shiro第13章Demo(RememberMe)

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

    Shiro学习教程源代码

    第十三章 RememberMe 第十四章 SSL 第十五章 单点登录 第十六章 综合实例 第十七章 OAuth2集成 第十八章 并发登录人数控制 第十九章 动态URL权限控制 第二十章 无状态Web应用集成 第二十一章 授予身份及切换身份 第...

    《Spring Security3》第四章第四部分翻译(Remember me后台存储和SSL)附前四章doc文件

    《Spring Security3》第四章第四部分主要探讨了Remember me服务的后台存储机制以及如何结合SSL(Secure Sockets Layer)来增强应用的安全性。这一部分的知识点涵盖了Spring Security中Remember me的功能,用户身份...

    acegi rememberMe和退出

    在Acegi Security中,"Remember Me"功能主要通过RememberMeServices接口实现,该接口定义了处理Remember Me令牌的方法。通常,这个令牌会被存储在用户的Cookie中,当用户下次访问时,如果Cookie存在且有效,系统会...

    CAS-4.0.3服务端RememberMe的Demo

    【CAS-4.0.3服务端RememberMe的Demo】是一个关于中央认证服务(Central Authentication Service,简称CAS)4.0.3版本中RememberMe功能的实战示例。RememberMe功能允许用户在登录时选择“记住我”,从而在一段时间内...

    81、Remember me设置1

    ### Symfony 5 Remember Me 功能详解 #### 一、引言 在现代Web应用中,为用户提供便捷且安全的登录体验至关重要。Symfony框架提供了一种称为“Remember Me”(记住我)的功能,允许用户选择自动登录,从而提高用户...

    vue登录页-记住密码功能

    1.下载jsencrypt 加密解密插件 ...Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }); } else { Cookies.remove("username"); Cookies.remove("password"); Cookies.remove('rememberMe'); }

    Spring Security Remember me使用及原理详解

    Spring Security Remember me使用及原理详解 Spring Security是一个广泛使用的安全框架,提供了许多功能来保护Web应用程序。在这些功能中,Remember me是其中的一个重要组件。它允许用户在登录时选择“记住我”,...

    acegi rememberMe

    【acegi rememberMe】是基于Acegi Security框架的一个特性,主要关注的是用户认证过程中的“记住我”功能。Acegi Security是Spring Security的前身,它为Spring应用提供了全面的安全管理框架,包括身份验证、授权、...

    rememberMe

    在"RememberMe"功能中,JavaScript主要负责交互逻辑,例如当用户勾选"RememberMe"选项时,触发相关事件,将用户的选择通过AJAX异步请求发送到服务器。 2. **Cookie机制** Cookie是浏览器为每个域维护的一系列小型...

    acegi rememberMe和匿名登录

    本文将深入探讨Acegi Security中的"rememberMe"功能以及匿名登录的实现机制。 "Remember Me"功能在许多Web应用中非常常见,它允许用户在登录后选择“记住我”,以便在未来的会话中自动登录,而无需每次都输入用户名...

    SHIRO-721:RememberMe填充Oracle漏洞RCE

    SHIRO-721 RememberMe填充Oracle漏洞RCE 0x00简介: cookie的cookiememeMe已通过AES-128-CBC模式加密,这很容易受到填充oracle攻击的影响。 攻击者可以使用有效的RememberMe cookie作为填充Oracle Attack的前缀,...

    Spring Security学习之rememberMe自动登录的实现

    当你启用`rememberMe`时,Spring Security会生成一个名为`REMEMBER_ME`的cookie,其中包含加密后的用户信息。默认情况下,这个cookie的有效期为两周。每次用户通过表单登录成功,Spring Security会更新这个cookie,...

    Remember me 钢琴改编版钢琴曲谱双手数字简谱钢琴曲谱.pdf

    《Remember Me》是一首深受喜爱的歌曲,常被用于各种场合,包括电影、电视剧和音乐会。这首曲子的钢琴改编版为演奏者提供了展现技巧和情感表达的机会。钢琴改编版通常会保留原曲的主要旋律线,并加入合适的伴奏,...

    Spring Security 构建rest服务实现rememberme 记住我功能

    "Spring Security 构建 REST 服务实现 RememberMe 记住我功能" Spring Security 是一个功能强大且灵活的安全框架,广泛应用于 Java Web 应用程序中。在本文中,我们将介绍如何使用 Spring Security 构建 REST 服务...

    CVE-2016-4437 Shiro550 & Shiro721 RememberMe Padding Oracle 漏洞利用

    CVE-2016-4437 Shiro550 & Shiro721 RememberMe Padding Oracle Shiro721 RememberMe Padding Oracle影响版本: - Apache Shiro 1.2.5,1.2.6,1.3.0,1.3.1,1.3.2,1.4.0-RC2,1.4.0,1.4.1 CVE-2016-4437 ...

    RememberMe

    《RememberMe:Kotlin打造的先进待办应用详解》 RememberMe是一款被誉为迄今为止最先进的待办事项应用程序,它凭借其高效、便捷的特性赢得了用户的广泛赞誉。在这个应用的背后,是强大的编程语言Kotlin的支撑,使得...

Global site tag (gtag.js) - Google Analytics