Security工作流程及代码分析

Spring Security工作原理

在了解了Security几个核心类的概念之后,我们梳理一下Security的工作原理。

本文将要分析的几个问题

security的工作流程,security的几个核心过滤器的功能,即什么时候把Authentication与线程绑定,什么时候进行认证,什么时候将Authentication与session关联,什么时候将Authentication改变更新到session,什么时候进行权鉴,没有认证信息及权限的时候是如何处理的。

工作流程

Filter我们都很熟悉了,其实security就是基于FIlter实现的,它的关键类FilterChainProxy的就是一个Filter。

带Security鉴权框架的系统整体过滤流程如下:

在这里插入图片描述

下面具体看看Spring Security Filters有哪些过滤器,跟踪FilterChainProxy的doFilters方法代码,发现其调用了doFilterInternal,在getFilters方法里打个断点,看看有哪些过滤链。

在这里插入图片描述

根据配置(这个配置的方法之后再讲,先把流程理清楚)生成了几个chain,可以看到一个典型的chain包含filters和requestMatcher,即不同的请求接口会选择到不同的filters。下面我们来分析几个主要的Filter。

SecurityContextPersistenceFilter

securityContext指的是认证信息(Authentication,里面存储着用户的信息),这个过滤器实现的功能从两个角度分析,一是请求进入,而是响应返回,请求进入时,该过滤器使用SecurityContext存储器(可以是默认的HttpSessionSecurityContextRepository,也可以是根据你的需求自己实现的,这里讲的是默认)从Session中获取SPRING_SECURITY_CONTEXT_KEY对应的属性值即SecurityContext,如果获取得到放入SecurityContextHolder(基于ThreadLocal实现的一个类,用于存储Authentication)。无论获取得到还是获取不到,都进入下一个过滤器。二是从响应返回的方向分析,该过滤器会使用SecurityContext存储器把securityContext存储起来。

中间几个过滤器跳过,其中有一些是我们项目实现的,重要程度不是很高,我们直接看BasicAuthenticationFilter过滤器。

BasicAuthenticationFilter

这个过滤器是基于Basic认证的过滤器,即当用户使用Basic方式(http的header里携带Authorization: Basic)登录时才会使用的过滤器。

在这里插入图片描述

当认证失败,会调用authenticationEntryPoint.commence(request, response, failed)方法进行失败逻辑处理,并直接return;过滤链不再继续。当认证成功,将Authentication设置进SecrutiyContextHolder,直接进入下一个过滤器(这里是basicAuthenticationFilter如此,其他认证型的Filter如UserNamePasswordFilter认证成功后会执行sessionStrategy.onAuthentication(authResult, request, response))。

SessionManagementFilter

这个Filter用来处理Session相关的内容有众多的配置项比如invalidSessionStrategy,sessionAuthenticationStrategy,总而言之,和session相关的都可以在此filter中操作。当securityContext不为空时会执行SessionAuthenticationStrategy.onAuthentication(authentication, request, response);注意这里是SessionAuthenticationStrategy比上一个提到的多了个Authentication词。接着会使用Context存储过滤器将securityContext存入session中。可以理解为插入,因为在响应返回时上面提到的第一个过滤器会进行更新。

ExceptionTranslationFilter

这个是用来处理异常的Filter,看它的doFilter()方法,只是直接到下一个过滤器,然后catch异常,根据异常类型来执行对应操作,这里只有两类异常一个是AuthenticationExcepriotn认证异常(没有认证信息,比如没带sessionId),AccessDeniedException权限异常。认证异常会authenticationEntryPoint.commence(request, response, reason);来处理,权限异常会accessDeniedHandler.handle(request, response, (AccessDeniedException) exception);来处理。

在这里插入图片描述

FilterSecurityInterceptor

这个过滤器是过滤链最后一个过滤器,主要是一个鉴权的作用。它会调用AbstractSecurityInterceptor的beforeInvocation(),如果没有认证信息则会抛出AuthenticationException,如果有认证信息,但是权限不足则会抛出

AccessDeniedException。这两个异常会给ExceptionTranslationFilter来处理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章