shiro过滤器
- 调用OncePerRequestFilter中的doFilter方法
- 调用AdviceFilter中的doFilterInternal方法
- 调用AdviceFilter中的preHandle、executeChain、postHandle方法
- 调用AccessControlFilter中的onPreHandle方法
- 调用AuthenticationFilter中的isAccessAlowed方法和FormAuthenticationFilter的onAccessDenied方法
AbstractFilter
位于shiro过滤器的最顶层,是个抽象方法,直接继承Filter
只做了一些基本的初始化操作,并没有实现Filter的doFilter方法
NameableFilter
允许通过getName和setName方式给过滤器命名
如果没有给该过滤器命名,那么默认将会使用web.xml中给定的名称(FilterConfig的filterName)
该类可以理解为为过滤器命名用的,也没有实现Filter的doFilter方法
OncePerRequestFilter
实现了Filter中doFilter的类
它用来保证在每个servlet容器上,每一个请求只会被过滤一次
通过getAlreadyFilteredAttributeName()方法来鉴别请求是否已经被过滤
实际业务处理写在doFilterInternal方法中
执行流程
- 判断过滤器是否已经执行过了,如果执行过则直接放行
- 判断过滤器是否开启,通过eabled变量实现,如果没有开启直接放行
- 这里分成3个步骤
- 将过滤器名称放入request中
- 调用doFilterInternal方法,执行真正的过滤器处理逻辑
- 这个过滤器处理完后,将过滤器的属性名从request中移除
AdviceFilter
这个过滤器,类似于aop的环绕通知
方法
- preHandle:前缀过滤,如果返回false,则说明过滤器不会执行chain.doFilter,意味着被拦截了
- postHandle:后置过滤
- afterCompletion:用来对异常进行处理
PathMatchingFilter
路径匹配过滤器作用是:根据路径匹配结果,调用相应过滤器
对配置了url请求拦截的地址进行过滤,对没有配置拦截的url放行,如果有过滤的逻辑则由子类的onPreHandle方法完成
- 判断:appliedPaths为空,则放行,不作连接请求的处理
- 如果用户的请求与配置中拦截的请求匹配,则会调用isFilterChainContinued方法, isFilterChainContinued 也是在PathMatchingFilter中实现的,作用是判断过滤器是否可用
- 如果拦截器是开启的,则调用onPreHandle进行拦截处理
- onPreHandle方法默认返回true,也不对请求进行拦截处理,所以如果需要自定义拦截,需要覆盖这个方法
AccessControlFilter
如果用户没有认证(登录),那么这个过滤器就是控制访问资源和用户重定向到登录页面和过滤器的父类
实现了PathMatchingFilter的onPreHandle方法
- isAccessAllowed:验证用户是否登录
- onAccessDenied:处理用户没有登录后的逻辑(需要子类实现逻辑)
AuthenticationFilter
此类封装了用户是否在系统中已经验证过的逻辑
处理登录验证实际上是isAccessAllowed和onAccessDenied这二个方法,这个类实现类isAccessAllowed的逻辑,而它的子类实现了onAccessDenied的逻辑
AuthenticatingFilter
提供了一些如登录、重定向的方法,并没有实现onAccessDenied方法
方法
- executeLogin:登录
- 从createToken中获取authenticationToken对象,这个对象包含了用户名密码
- 进行登录操作
- 成功:执行onLoginSuccess默认返回true
- 失败:执行onLoginFailure默认返回false
FormAuthenticationFilter
对用户进行身份认证,以便请求继续,如果没有认证,则强制让该请求重定向到配置文件的登录url
onAccessDenied方法
- isLogRequest:验证是否是登录请求,
- 如果不是登录请求,直接通过saveRequestAndRedirectToLogin方法返回到登录页面
- 如果是登录请求,则通过isLoginSubmission判断是否是http的post
- 如果不是,说明用户请求的是登录页面的get请求,直接放行就可以了
- 如果是,说明用户访问的是登录的url请求,那么就执行executeLogin方法做操作
onLoginSuccess方法
- 执行issueSuccessRedirect方法重定向到登录页面
- 返回false
onLoginFailure方法
- 在request中存入失败原因
- 返回true