Shiro的authc过滤器的执行流程

1.先执行isAccessAllowed(),通过subject.isAuthenticated()判断当前session中的subject是否已经登陆过。如果在当前session即会话中已经登陆过,返回true,authc过滤器放行请求到loginUrl。
问题?
这里会有一个问题,如果我登陆成功后,再次访问loginUrl,会执行isAccessAllowed()并返回true放行,那么我访问到了loginUrl,如果此时我在loginUrl中输入新的用户名密码,再提交则先执行isAccessAllowed(),因为当前session中的subject是已经登陆过的,isAccessAllowed()返回true,autch放行,请求又会到loginUrl。因为在登陆的情况下,再访问loginUrl则isAccessAllowed()始终返回true,不会执行到onAccessDenied()方法,即不会验证请求中的新的用户名和密码。
2.如果isAccessAllowed()是false即拒绝访问后执行onAccessDenied()方法:
2.1判断是否是登陆请请求(即request中的url和我们设置的loginUrl是否一致)
2.1.1如果请求的url和我们在配置文件中设置的loginUrl一样
2.1.1.1如果是get请求,则返回true,即该过滤器连放行,让请求访问到loginUrl
2.1.1.2如果是post请求,则创建subjet和tocken 调用subject的login方法进行认证(即开始执行realm的doGetAuthenticationInfo方法)
2.1.1.2.1如果认证成功则会返回false阻止filterChain继续执行即不让请求达到loginUrl,而是在这里直接重定向我们上次访问的非logurl的请求地址去(这个请求地址在你访问的时候已经被保存到session中了)如果没有上次访问的地址,则到我们设置的SuccessUrl
2.1.1…2.2如果认证失败则会返回true,将认证失败的异常信息放到reqeust属性中,即放行让fliterChain继续执行,让请求达到loginUrl。
2.2如果否即request中的url不是loginUrl,则保存请求(应该是到session里),再将请求重定向到loginUrl(浏览器又会访问通过get方法访问loginUrl,又会被authc拦截,再重複上面流程,此时是登陆请求且是GET请求则authc会放行访问到loginUrl),执行完重定向后返回false阻止filterChain继续执行。

综上所述:
只有以下四种情况会到loginUrl:
//1.还没有登陆成功的情况下:get请求我们在配置文件中设置的loginUrl,authc会放行请求到这里
//2.还没有登陆成功的情况下:post请求我们在配置文件中设置的loginUrl,authc在认证失败后会让浏览器重定向到这里
//3.还没有登陆成功的情况下:请求(不管post还是get)的页面不是loginUrl且需要authc过滤,那么authc也会让浏览器重定向到这里
//4.登陆成功后,浏览器再次访问loginUrl(不管post或get),authc也会放行到这里。
怎么解决上面登陆成功后再访问loginUrl,不会执行新用户认证的问题呢?只有重写authc过滤器的isAccessAllowed()方法

public class MyAuthcFilter extends FormAuthenticationFilter {@Overrideprotected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue){System.out.println("执行自定义过滤");//如果请求的是loginUrl 并且是POST请求,那么肯定是要验证密码的,这里直接返回false 就会执行onAcessDenied()方法if (isLoginRequest(request, response) && isLoginSubmission(request, response)){return false;}//如果是其他请求 则执行父类的方法return super.isAccessAllowed(request, response, mappedValue);}
}

最后再配置文件中注册该类,覆盖掉shiro原本的过滤器FormAuthenticationFilter:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><property name="securityManager" ref="securityManager" /><property name="loginUrl" value="/login" /><property name="successUrl" value="/index.jsp" /><property name="unauthorizedUrl" value="/unauthorized.jsp" /><property name="filters"><map><entry key="authc" value-ref="myAuthcFilter" /></map></property><property name="filterChainDefinitions"><value># some example chain definitions:/login = authc/logout = logout/1.jsp = user/** = authc# more URL-to-FilterChain definitions here</value></property></bean>

login的写法:

@Controller
public class UsersController {@RequestMapping("login")public String login(HttpServletRequest req) {//只有//1.还没有登陆成功的情况下:get请求我们在配置文件中设置的loginUrl,authc会放行请求到这里//2.还没有登陆成功的情况下:post请求我们在配置文件中设置的loginUrl,authc在认证失败后会让浏览器重定向到这里//3.还没有登陆成功的情况下:请求(不管post还是get)的页面不是loginUrl且需要authc过滤,那么authc也会让浏览器重定向到这里//4.登陆成功后,浏览器再次访问loginUrl(不管post或get),authc也会放行到这里。如果我们在自定义的过滤器中//设置成如果是POST请求的loginUrl,我们返回false。那么post请求的loginUrl就会执行在过滤器中执行onAcessDenied()方法,如果post的loginUrl验证失败了会到这里,如果验证成功则到secessUrl这里。String errorClassName = (String) req.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);if(UnknownAccountException.class.getName().equals(errorClassName)) {req.setAttribute("error", "用户名/密码错误");} else if(IncorrectCredentialsException.class.getName().equals(errorClassName)) {req.setAttribute("error", "用户名/密码错误");} else if(errorClassName != null) {req.setAttribute("error", "未知错误:" + errorClassName);}return "login.jsp";}
}

session和cookie:
通过浏览器第一次发送http请求时,服务器会创建一个session和cookie(cookie中保存sessionid),这个session服务器的默认时间30分钟,可以设置。服务第一次响应时也把cookie放到响应中给浏览器,浏览器
收到cookie后,会判断cookie有没有设置过期时间,如果没有则只保存在内存中。如果有则存到硬盘里。
如果只是保存到内存中,服务器端的session依然会保留30分钟。那么浏览器一关闭,cookie消失,sessionid也消失了。。但此时打开浏览器再访问服务器时,虽然服务器的session依然存在,但浏览器中的cookie(sessionid)消失了
浏览器发送的请求头里没有cookie(没有sessionid),服务器会当作一个新的请求,会再创建一个新session。服务器中的之前的session 30分钟侯清除。
如果保存到硬盘里了, 服务器端的session依然会保留30分钟。那么关闭浏览器后,再打开浏览器访问服务器时,浏览器会找到存到硬盘里的cookie(sessionId), 浏览器再次请求服务器时会带上cookie,服务器收到请求后发现有cookie(sessionId)并且服务器
端的session也存在。那么服务器就依然会使用之前的session。不会再创建一个新的session。
所以session默认关闭浏览器就失效了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/250068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot之基础

简介 背景 J2EE笨重的开发 / 繁多的配置 / 低下的开发效率 / 复杂的部署流程 / 第三方技术集成难度大 特点 ① 快速创建独立运行的spring项目以及主流框架集成 ② 使用嵌入式的Servlet容器, 应用无需达成war包 ③ starters自动依赖和版本控制 ④ 大量自动配置, 简化开发, 也可修…

[Java核心技术(卷I)] - vscode手动编译运行继承类

参考 - P160~P161 主要有3个类: 一个测试类(ManagerTest)、一个子类(Manager)、一个父类(Employee) 注意点: -1. 使用 javac -d . *.java进行预编译 目录结构入下: 此时会生成目录结构如下: 之后运行 java com.inheritance.ManagerTest 附上几个类的代码 // com.inhe…

mysql常用语句和函数

mysql语句如果长期不写&#xff0c;就会忘掉&#xff0c;所以要时常复习&#xff0c;温故而知新。 1.select length("中国人"),select char_length("中国人"); 2建立数据库的语句 use new_schema;create table ta(id int primary key);这是小括号&#xff…

shiro框架@RequiresPermissions 解释

RequiresAuthentication 验证用户是否登录&#xff0c;等同于方法subject.isAuthenticated() 结果为true时。 RequiresUser 验证用户是否被记忆&#xff0c;user有两种含义&#xff1a; 一种是成功登录的&#xff08;subject.isAuthenticated() 结果为true&#xff09;&…

【Social Listening实战】当数据分析遭遇心理动力学:用户深层次的情感需求浮出水面...

本文转自知乎 作者&#xff1a;苏格兰折耳喵 ————————————————————————————————————————————————————— 本文篇幅较长&#xff0c;分为五部分&#xff0c;在中间部分有关于心理分析工具的介绍&#xff0c;案例分散在第二部…

Python 字符串切片

#-*- coding:utf-8 -*-#字符串切片names "abcdefgh"切片语法 names[起始位置:终止位置:步长] 起始位置:即字符串的下标&#xff0c;可以是正序下标(0,1,2...)&#xff0c;也可以是逆序下标(-1,-2,-3...) 终止位置:也是字符串的下标&#xff0c;但是和起始位置下标不…

[Java核心技术(卷Ⅰ)] - 判断相等

参考 - P184 public boolean equals(Object otherObject) {// a quick test to see if the objects are identicalif (this otherObject) return true;// must return false if the explicit parameter is nullif (otherObject null) return null;// if the classes dont ma…

Oracle 11g DG主库节点2 ORA-00245: control file backup fail

--节点1报错 Sun Dec 09 08:29:57 2018Control file backup creation failed: failure to open backup target file /u01/app/oracle/product/11.2.0/db_1/dbs/snapcf_zwdb.ctl.Errors in file /u01/app/oracle/diag/rdbms/zwdb/zwdb2/trace/zwdb2_arc0_167660.trc:ORA-27037: …

hive字符函数

转载于:https://www.cnblogs.com/ggzhangxiaochao/p/9222732.html

java动态编译

编译&#xff0c;一般来说就是将源代码转换成机器码的过程&#xff0c;比如在C语言中中&#xff0c;将C语言源代码编译成a.out,&#xff0c;但是在Java中的理解可能有点不同&#xff0c;编译指的是将java 源代码转换成class字节码的过程&#xff0c;而不是真正的机器码&#xf…

[c++] - 简单的冒泡

#include <iostream> using namespace std;int main() {// 利用冒泡排序实现升序序列int arr[9] {4, 2, 8, 0, 5, 7, 1, 3, 9};cout << "排序前: " << endl;for (int i 0; i < 9; i){cout << arr[i] << " ";}cout <…

Python爬虫之解析网页

常用的类库为lxml, BeautifulSoup, re(正则) 以获取豆瓣电影正在热映的电影名为例,urlhttps://movie.douban.com/cinema/nowplaying/beijing/ 网页分析 部分网页源码 <ul class"lists"><liid"3878007"class"list-item"data-title"…

腾讯企业邮箱报错 smtp.exmail.qq.comport 465, isSSL false

一、报错 "smtp.exmail.qq.com" port 465, isSSL false 通过网上搜索查询一些资料&#xff0c;推测是邮箱的配置出问题了。 二、修改邮箱配置 1 // 创建属性2 Properties props new Properties();3 props.setProperty("mail.transport.protocol", "s…

spring与JDK版本对应关系

搭建spring框架得时候要考虑jdk的版本&#xff0c;提供一下参考 JDK 8 中可以使用 Spring Framework 5.x JDK 7 中可以使用 Spring Framework 4.x JDK 6 中可以使用 Spring Framework 4.x JDK 5 中可以使用 Spring Framework 3.x

Markdown预览功能不可用解决方案

初学者在使用Markdown时也许会遇到这个问题 原因是电脑缺少一个组件&#xff0c;解决方案很简单&#xff0c;安装上就好了&#xff0c;以下是链接 http://markdownpad.com/download/awesomium_v1.6.6_sdk_win.exe转载于:https://www.cnblogs.com/j9oker/p/10092829.html

Linux 中yum的配置

1.进入yum的路径 cd /etc/yum.repos.d 2.将原始的repo文件移入一个新建的backup文件下做备份 mv CentOS* backup 3.在/etc/yum.repos.d下新建一个自己的文件(这里的文件必须以repo结尾); vi zhi.repo 其中&#xff0c;第一行必须是[文件名]的格式  是一个标记 name*** 这是一…

[生态建设] - js判断小技巧

0、参考 说明: 从几个易得的点出发,逐步向外扩展延申,保证代码的可靠性 1、判断是否为某个类型 // 判断是否为 null const isNull o > {return o null; };// 判断是否为 undefined const isUndefined o > {return o undefined; };// 判断是否为 null or undefined…

Spring中Bean的概念

一、Bean的定义 <beans…/>元素是Spring配置文件的根元素&#xff0c;<beans…/>元素可以包含多个<bean…/>子元素&#xff0c;每个<bean…/>元素可以定义一个Bean实例&#xff0c;每一个Bean对应Spring容器里的一个Java实例定义Bean时通常需要指定两…

[TJOI2010]阅读理解

题目描述 英语老师留了N篇阅读理解作业&#xff0c;但是每篇英文短文都有很多生词需要查字典&#xff0c;为了节约时间&#xff0c;现在要做个统计&#xff0c;算一算某些生词都在哪几篇短文中出现过。 输入输出格式 输入格式&#xff1a; 第一行为整数N&#xff0c;表示短文篇…

ccentos 7下安装php5.6并使用nginx + php-fpm部署多个不同端口网站

作为一个的勤杂工&#xff0c;近期因公司内部信息化的需求&#xff0c;给新进员工提供基础的知识培训和介绍&#xff0c;也为了给公司内部建立一个沟通交流的平台&#xff0c;百度找了开源的百科系统HDwiki和开源的问答系统Tipask问答系统&#xff0c;蛋痛的这两套系统均是phpm…