文章目录

  • 1.Remember me简介
  • 2.登录表单中添加记住我复选框
  • 3.配置文件中配置
  • 4.登录控制器
  • 5.测试

1.Remember me简介

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

1.首先在登录页面选中RememberMe然后登录成功;如果是浏览器登录,一般会把RememberMe的Cookie写到客户端并保存下来;
2.关闭浏览器再重新打开;会发现浏览器还是记住你的;
3.访问一般的网页服务器端还是知道你是谁,且能正常访问;

2.登录表单中添加记住我复选框

<body style="background-image: url('/images/44444.jpg')"><form action="/user/login" method="post">账号:<input type="text" name="username" ><br/>密码:<input type="password" name="password"><br/><input type="checkbox" value="true" name="rememberMe">记住密码<br/><input type="submit" value="提交"><span th:text="${msg}" style="color: red"></span></form>
</body>

1.shiro 提供记住我的功能,当将form表单中name=“rememberMe” 的value设为true或者登陆的token中。token.setRememberMe(true) 的时候,用户关闭浏览器之后,现在进入需要认证的资源的时候就不需要再登陆。

2.form表单中的value不仅仅只有true 的状态位,还可以设置t、1、enabled、y、yes、on这集中状态位都表示记住我。

3.配置文件中配置

<!--rememberMe cookie-->
<bean id="rememberMe" class="org.apache.shiro.web.servlet.SimpleCookie"><constructor-arg  value="rememberMe"></constructor-arg><property name="httpOnly" value="true"></property><!--cookie 的最大失效时间 30天--><property name="maxAge" value="259200"></property>
</bean>

maxAge=-1 表示关闭浏览器cookie失效

<!--rememberMe 管理器--><bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"><property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"></property><property name="cookie" ref="rememberMe"></property></bean>

cipherKey:表示设置cookie的加密算法,采用的是base64的加密

<!--form表单验证的过滤器--><bean id="formAuthenticationFilter" class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"><!--loginName 对应form表单的用户名--><property name="usernameParam" value="username" /><!--password 对应form表单的密码--><property name="passwordParam" value="password" /><!--rememberMe 记住我checkbox 是否记住我默认为false--><property name="rememberMeParam" value="rememberMe" /><!--form 的action--><property name="loginUrl" value="/user/login" /></bean>

form表单登陆的过滤器,这个过滤器对应的认证key是authc,当登陆的请求匹配到这个key的时候,就将这个过滤器加入到当前请求的过滤器链中。

<!--指定shiro的核心管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><!--可以设置一个或者多个安全域--><property name="realm" ref="customRealm" /><!-- 会话管理 --><property name="sessionManager" ref="sessionManager" /><!--记住我--><property name="rememberMeManager" ref="rememberMeManager"/>
</bean>

将rememberMe的管理器交给securityManager 管理。

<!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 --><!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 --><!--ShiroFilterFactoryBean 是一个shiroFilter的工厂类,负责实例化过滤器--><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- Shiro的核心安全接口,这个属性是必须的 --><property name="securityManager" ref="securityManager"/><!-- 要求登录时的链接,当request请求被解析为需要认证则跳转到这个链接进行登录 --><property name="loginUrl" value="/shiro/goLogin"/><!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) --><!-- <property name="successUrl" value="/system/main"/> --><!-- 用户访问未对其授权的资源时,所显示的连接 --><!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp,然后用[玄玉]登录后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp --><property name="unauthorizedUrl" value="/"/><!-- Shiro连接约束配置,即过滤链的定义 --><!-- 此处可配合这篇文章来理解各个过滤连的作用http://blog.csdn.net/jadyer/article/details/12172839 --><!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 --><!--shiro的默认过滤器分为两种:认证过滤器:anon,authcBasic,auchc,user 和授权过滤器:perms,roles,ssl,rest,port--><!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 --><!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter --><!-- user: 表示身份验证通过,或者记住我--><!-- rememberMe:记住我设置后不用再需要登录--><property name="filterChainDefinitions"><value><!--加载顺序从上往下。authc需要认证anon可以匿名访问的资源--><!--可以匿名访问(不用认证)-->/user/loginUI=anon/user/login=anon/images/**=anon<!--权限控制-->/user/add=perms[user:create]/user/update=perms[user:update]/user/delete=perms[user:delete]/user/list=perms[user:list]<!--剩余资源全部需要登录认证-->/**=user</value></property></bean>

4.登录控制器

   /*** 设定登录失败跳转的资源以及获取失败的信息* @param model* @return*/@RequestMapping("login")public String login(Model model,String username,String password,@RequestParam(defaultValue = "false") Boolean rememberMe){System.out.println("rememberMe="+rememberMe);//添加用户认证信息Subject subject = SecurityUtils.getSubject();//登录令牌UsernamePasswordToken token = new UsernamePasswordToken(username,password);//6.模拟登录try {//设置记住我token.setRememberMe(rememberMe);// 登录操作subject.login(token);String userName = (String) subject.getPrincipal();System.out.println("登录账户:"+userName);Session session = subject.getSession();session.setAttribute("userName", userName);return "redirect:/page/index";} catch (UnknownAccountException e) {model.addAttribute("msg","账号出错");} catch (IncorrectCredentialsException e) {model.addAttribute("msg","密码出错");}return "login";}

5.测试

启动server容器之后:

点击登陆之后,当登陆成功之后会调用DefaultSecurityManagerrememberMeSuccessfulLogin方法将记住我写入到cookie中

protected void rememberMeSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) {RememberMeManager rmm = getRememberMeManager();if (rmm != null) {try {rmm.onSuccessfulLogin(subject, token, info);} catch (Exception e) {if (log.isWarnEnabled()) {String msg = "Delegate RememberMeManager instance of type [" + rmm.getClass().getName() +"] threw an exception during onSuccessfulLogin.  RememberMe services will not be " +"performed for account [" + info + "].";log.warn(msg, e);}}} else {if (log.isTraceEnabled()) {log.trace("This " + getClass().getName() + " instance does not have a " +"[" + RememberMeManager.class.getName() + "] instance configured.  RememberMe services " +"will not be performed for account [" + info + "].");}}}

之后再调用RememberManager的onSuccessfulLogin方法

protected void rememberSerializedIdentity(Subject subject, byte[] serialized) {if (!WebUtils.isHttp(subject)) {if (log.isDebugEnabled()) {String msg = "Subject argument is not an HTTP-aware instance.  This is required to obtain a servlet " +"request and response in order to set the rememberMe cookie. Returning immediately and " +"ignoring rememberMe operation.";log.debug(msg);}return;}HttpServletRequest request = WebUtils.getHttpRequest(subject);HttpServletResponse response = WebUtils.getHttpResponse(subject);//serialized 是princple经过序列化之后的数据,将序列话的数据base64位编码String base64 = Base64.encodeToString(serialized);Cookie template = getCookie(); //the class attribute is really a template for the outgoing cookiesCookie cookie = new SimpleCookie(template);cookie.setValue(base64);      //设置记住我的cookiecookie.saveTo(request, response);}

继续跟踪会到设置cookie 的方法

protected void rememberSerializedIdentity(Subject subject, byte[] serialized) {if (!WebUtils.isHttp(subject)) {if (log.isDebugEnabled()) {String msg = "Subject argument is not an HTTP-aware instance.  This is required to obtain a servlet " +"request and response in order to set the rememberMe cookie. Returning immediately and " +"ignoring rememberMe operation.";log.debug(msg);}return;}HttpServletRequest request = WebUtils.getHttpRequest(subject);HttpServletResponse response = WebUtils.getHttpResponse(subject);//serialized 是princple经过序列化之后的数据,将序列话的数据base64位编码String base64 = Base64.encodeToString(serialized);Cookie template = getCookie(); //the class attribute is really a template for the outgoing cookiesCookie cookie = new SimpleCookie(template);cookie.setValue(base64);      //设置记住我的cookiecookie.saveTo(request, response);}


登陆成功的cookie

关闭浏览器,访问/user/index将可以直接访问,不会跳转到登录页面

《Shiro安全框架》专题(十)-Shiro之rememberMe相关推荐

  1. Shiro安全框架的使用

    Shiro安全框架 1.介绍 Shiro有三个核心的概念:Subject.SecurityManager和Realms. Subject(主体): subject本质上是当前正在执行的用户的特定于安全 ...

  2. 大数据WEB阶段 shiro安全控制框架

    shiro安全框架 零.目录 问题引申 shiro介绍 shiro工作流程 使用shiro 进行登录操作 使用shiro进行权限管理 一. 问题引申 需要实现的功能: 用户没有登录的情况下 , 处理登 ...

  3. shiro subject.getprincipal()为null_(变强、变秃)Java从零开始之Shiro安全框架

    Shiro安全框架 一.Shiro简介 二.Shiro架构图 三.Shiro涉及常见名词 四.Shiro配置文件详解 shiro.ini 文件放在 classpath 下 ,shiro 会自动查找.其 ...

  4. Shiro安全框架【SpringBoot版】

    文章目录 Shiro安全框架 一. 入门概述 1.1.Shiro是什么 1.2.为什么使用Shiro 1.3.Shiro与Spring Security的区别 1.4.基本功能 1.4.1.主要功能 ...

  5. Shiro安全框架最全面解析

    Shiro 一.权限框架介绍 1. 什么是权限管理 权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资源.   权限管理包 ...

  6. Shiro 权限框架使用总结

    我们首先了解下什么是shiro ,Shiro 是 JAVA 世界中新近出现的权限框架,较之 JAAS 和 Spring Security,Shiro 在保持强大功能的同时,还在简单性和灵活性方面拥有巨 ...

  7. Shiro安全框架【快速入门】就这一篇!

    Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...

  8. Shiro安全框架入门篇

    一.Shiro框架介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加 ...

  9. SpringBoot2.x 整合 shiro 权限框架

    每天早上七点三十,准时推送干货 在实际项目中,经常需要用到角色权限区分,以此来为不同的角色赋予不同的权利,分配不同的任务.比如,普通用户只能浏览:会员可以浏览和评论:超级会员可以浏览.评论和看视频课等 ...

最新文章

  1. MySQL server PID file could not be found!
  2. TensorFlow配置日志等级
  3. java反射 面试题_使用Java反射更改私有静态最终字段
  4. gsonformat插件_收藏非常有用的IDEA插件,没用过这些IDEA插件?怪不得写代码头疼
  5. file watchers怎么默认打开_Python读写文件怎么和我之前学的不一样?
  6. Java高级程序猿技术积累
  7. html5语音读取文字_文字识别神器最新版-文字识别神器安卓版下载
  8. 第 6 章 本地方法接口
  9. 电脑无限重启rpc服务器不可用,StarUML启动时候出现System Error. Code:1722. RPC服务器不可用.错误的解决办法...
  10. Anaconda 国内镜像配置
  11. githua 账号合并_如何合并他人的分支 github
  12. 一个Mysql触发器例子--状态改变的同时更新同表中的另一字段
  13. 全局空间自相关算法:Join Count
  14. PHP之阿里云短信接口接入
  15. python中write是什么意思_Python中操作文件之write()方法的使用教程
  16. 2020.7.6 -- Miller_Rabin和Pollard_Rho算法
  17. 通俗易懂物联网(1):什么是物联网?
  18. 3分钟用C语言教你写个‘浪漫烟花‘---特别漂亮
  19. GPU视频压缩2—Multiple Layer Parallel Motion Estimation on GPU for High Efficiency Video Coding (HEVC)
  20. 云原生分布式数据库云平台技术选择

热门文章

  1. 各种神字体来袭,圈子球迷用书法作品为国足呐喊加油!
  2. 视频编解码之关于AI、RA、LD的解释
  3. 【C++】「JSOI-2008」魔兽地图DotR
  4. 谭浩强c语言课后习题笔记[第6章]
  5. LINUX串口驱动分析——发送数据
  6. C++ 抓取和批量下载网站上的图片或文件
  7. SQL Exists ⚡️Group by ⚡️Case when ⚡️Having ⚡️常用函数
  8. SQL中如何使用EXISTS替代IN
  9. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : M
  10. 魔兽真正产品经理是古尔丹,来看看他的工具型产品是什么