Spring Security学习记录(二) -- Spring Security的Filter

来源:互联网 发布:.php打开乱码怎么解决 编辑:程序博客网 时间:2024/06/06 19:23

上一篇学习了Spring Security是如何拦截请求,并把请求转向到Filter链的,该篇就主要学习下这些Filter链的节点的作用.


下面是之前配置的内容,本文也是对这些内容 的执行分析.

<security:http >        <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>        <security:form-login/>        <security:http-basic/>        <security:logout/>    </security:http>    <security:authentication-manager>        <security:authentication-provider>            <security:user-service>                <security:user name="user" password="123456" authorities="ROLE_USER"/>                <security:user name="admin" password="123456" authorities="ROLE_USER, ROLE_ADMIN"/>            </security:user-service>        </security:authentication-provider>    </security:authentication-manager>

1.Filter链的由来

由上文可知每一个security:http标签实际上对应的是一个SecurityFilterChain的类,也就是一条Filter链,可以通过其http属性指明其作用的URL,否则作用域全部的URL,如下配置,该security:http会产生一个对/login下的所有请求Filter链.

    <security:http pattern="/login/**">        ******    </security:http>

打个断点可以很清楚的看到该Filter链

2.SecurityContextPersistenceFilter

该类在所有的Filter之前,是从SecurityContextRepository中取出用户认证信息,默认实现类为HttpSessionSecurityContextRepository,其会从Session中取出已认证用户的信息,提高效率,避免每一次请求都要查询用户认证信息.
取出之后会放入SecurityContextHolder中,以便其他filter使用,该类使用ThreadLocal存储用户认证信息,保证了线程之间的信息隔离,最后再finally中清除该信息.
可以配置http的security-context-repository-ref属性来自己控制获取到已认证用户信息的方式,比如使用redis存储session等.

3.WebAsyncManagerIntegrationFilter

提供了对securityContext和WebAsyncManager的集成,其会把SecurityContext设置到异步线程中,使其也能获取到用户上下文认证信息.

4.HeaderWriterFilter

其会往该请求的Header中添加相应的信息,在http标签内部使用security:headers来控制.

5.CsrfFilter

Csrf,跨站请求伪造,了解不是很深,只知道B网站使用A网站的可信Cookie发起请求,从而完成认证,伪造出正当请求.
验证方式是通过客户端传来的token与服务端存储的token进行对比,来判断是否为伪造请求,有兴趣的可以查看源代码研究下.

6.LogoutFilter

匹配URL,默认为/logout,匹配成功后则用户退出,清除认证信息.

7.UsernamePasswordAuthenticationFilter

登录认证过滤器,默认是对/login的POST请求进行认证,首先该方法会先调用attemptAuthentication尝试认证获取一个Authentication的认证对象,然后通过sessionStrategy.onAuthentication执行持久化,也就是保存认证信息,转向下一个Filter,最后调用successfulAuthentication执行认证后事件.

attemptAuthentication
该方法是认证的主要方法,认证是委托配置的authentication-manager->authentication-provider进行.
比如对于该Demo配置的为如下,则默认使用的manager为ProviderManager,使用的provider为DaoAuthenticationProvider,userDetailService为InMemoryUserDetailsManager也就是从内存中获取用户认证信息,也就是下面xml配置的user与admin信息.

    <security:authentication-manager>        <security:authentication-provider>            <security:user-service>                <security:user name="user" password="123456" authorities="ROLE_USER"/>                <security:user name="admin" password="123456" authorities="ROLE_USER, ROLE_ADMIN"/>            </security:user-service>        </security:authentication-provider>    </security:authentication-manager>

认证基本流程为UserDeatilService根据用户名获取到认证用户的信息,然后通过UserDetailsChecker.check对用户进行状态校验,最后通过additionalAuthenticationChecks方法对用户进行密码校验成功后完成认证.返回一个认证对象.

都是面向接口编程,所以用户可以很轻松的扩展自己的验证方式.

8.DefaultLoginPageGeneratingFilter

当请求为登录请求时,生成简单的登录页面返回

9.BasicAuthenticationFilter

Http Basci认证的支持,该认证会把用户名密码使用base64编码后放入header中传输,如下所示,认证成功后会把用户信息放入SecurityContextHolder中.

 * Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

10.RequestCacheAwareFilter

恢复被打断的请求,具体未研究

11.SecurityContextHolderAwareRequestFilter

针对Servlet api不同版本做的一些包装

12.AnonymousAuthenticationFilter

SecurityContextHolder中认证信息为空,则会创建一个匿名用户存入到SecurityContextHolder

13.SessionManagementFilter

与登录认证拦截时作用一样,持久化用户登录信息,可以保存到session中,也可以保存到cookie或者redis中.

14.ExceptionTranslationFilter

异常拦截,其处在Filter链后部分,只能拦截其后面的节点并且着重处理AuthenticationExceptionAccessDeniedException两个异常.

15.FilterSecurityInterceptor

主要是授权验证,方法为beforeInvocation,在其中调用

Collection<ConfigAttribute> attributes = this.obtainSecurityMetadataSource()                .getAttributes(object);

获取到所配置资源访问的授权信息,对于上述配置,获取到的则为hasRole('ROLE_USER'),然后根据SecurityContextHolder中存储的用户信息来决定其是否有权限,没权限则返回403,具体想了解可以关注HttpConfigurationBuilder.createFilterSecurityInterceptor()方法,分析其创建流程加载了哪些数据,或者分析SecurityExpressionOperations的子类,其是权限鉴定的实现方法.

总结

整个认证授权流程如下图所示,图是网上盗的

因为是学习方面,使用的不是很多,如有错误请指出,以防误人子弟.
简单来说,作为用户需要关心的地方是
1. 登录验证UsernamePasswordAuthenticationFilter
2. 访问验证BasicAuthenticationFilter
3. 权限验证FilterSecurityInterceptor
下一篇则讲述利用这三个验证实现JWT验证.

关于这些过滤器更详细的内容可参考博客: http://www.iteye.com/blogs/subjects/spring_security

github地址: https://github.com/nl101531/JavaWEB

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子和同学发生矛盾家长该怎么办 孩子同学给孩子要东西家长该怎么办 如果遇到不讲理的孩子和家长怎么办 孩子调皮又被老师留校了怎么办 孩子拼音f和sh发音不清怎么办 自己在家生的孩子怎么办出生证明 在家念地藏经招来众生不走怎么办 家是济宁孩子上学想在济南上怎么办 高一孩子成绩严重下滑家长怎么办 商铺租客不交租金又不搬走怎么办 考试试卷找不到了明天要交怎么办 8个月宝宝不爱吃蔬菜泥怎么办 5个月的宝宝拉肚怎么办 一岁宝宝大便拉不出来怎么办 八个月宝宝便秘拉不出来怎么办 10个月宝宝大便拉水怎么办 4个月的孩子大便拉水怎么办 五个多月宝宝大便拉水怎么办 七个月宝宝大便还没成行怎么办 宝宝一岁了还没长牙怎么办 宝宝什么都会就差不会独占怎么办 两岁宝宝肚子不舒服还吐怎么办 两岁宝宝吃坏肚子吐怎么办 1岁半儿童牙烂了怎么办 一岁宝宝吃了就吐怎么办 两岁宝宝龋齿门牙掉了怎么办 一岁宝宝冻着了呕吐怎么办 两岁宝宝喉咙有痰呼呼响怎么办 1岁宝宝吐的水水怎么办 宝宝吐了5 6次了怎么办 7岁儿童吃了就吐怎么办 狗狗拉稀呕吐不吃饭只喝水怎么办 宝宝吃坏肚子上吐下泄怎么办 一岁宝宝又吐又拉怎么办 八个月宝宝吃什么吐什么怎么办 九个月宝宝吃什么吐什么怎么办 三岁宝宝吃什么吐什么怎么办 2岁宝宝又拉又吐怎么办 6岁儿子又吐又拉怎么办 2岁宝宝吃了就吐怎么办 宝宝吃饱了就吐吐了在吃怎么办