SpringSecurity源码解析

第一节

SpringSecurity的顶层脉络以及几个核心的类

SecurityBuilder

用于构建对象的接口

SpringSecurity源码解析_第1张图片

HttpSecurity

SpringSecurity源码解析_第2张图片

WebSecurity

SecurityFilterChain

定义能够与HttpServletRequest匹配的筛选器链。以便决定它是否适用于该请求

SpringSecurity源码解析_第3张图片

实现类: DefaultSecurityFilterChain

SpringSecurity源码解析_第4张图片

FilterChainProxy

SpringSecurity进入流程

FilterChainProxy ->根据请求决定一个SecurityFilterChain ->执行SecurityFilterChain中的一系列过滤器

第二节

主要下面三个类:

HttpSecurity内幕

SecurityConfigurer

所有SecurityConfigurer首先调用其init(SecurityBuilder)方法。在调用了所有init(SecurityBuilder)方法之后,将调用每个configure(SecurityBuild)方法

SpringSecurity源码解析_第5张图片

AbstractConfiguredSecurityBuilder

AbstractConfiguredSecurityBuilder是Spring Security Config对安全构建器SecurityBuilder的抽象基类实现。它继承自安全构建器SecurityBuilder的另外一个抽象基类实现AbstractSecurityBuilder。但不同的是,AbstractSecurityBuilder约定了SecurityBuilder构建的基本框架:最多被构建一次,而AbstractConfiguredSecurityBuilder在此基础上做了如下扩展:

  • 允许将多个安全配置器SecurityConfigurer应用到该SecurityBuilder上;

  • 定义了构建过程的生命周期(参考生命周期状态定义BuildState);

  • 在生命周期基础之上实现并final了基类定义的抽象方法#doBuild,将构建划分为三个主要阶段#init,#configure,#performBuild;

    1. 对 #init/#configure阶段提供了实现;

    2. 对 #init/#configure阶段提供了前置回调#beforeInit/#beforeConfigure空方法供基类扩展;

    3. #performBuild定义为抽象方法要求子类提供实现;

  • 登记安全构建器工作过程中需要共享使用的一些对象。

performBuild

 子类必须实现此方法来构建要返回的对象。返回: 要设置的对象,如果实现允许,则返回 null

postProcess

执行对象的后处理。默认是委托给 ObjectPostProcessor。参数:对象——要发布的对象返回:可能修改的要使用的对象

SpringSecurity源码解析_第6张图片

 无法通过配置解决的可以自己实现这个接口。

小结

SecurityBuilder用来构建安全对象,安全对象包括:HtpSecurity、FilterChainProxy、AuthenticationManager SecurityConfigurer用来配置安全对象构建器(SecurityBuilder) ,典型的有:FormLoginConfigurer、CsrfConfigurer等

第三节

Authentication

代表身份验证请求的token或者经过身份验证的principal,一旦 AuthenticationManager.authenticate(Authentication) 方法处理了请求

主要方法

SpringSecurity源码解析_第7张图片

AuthenticationManager

 SpringSecurity源码解析_第8张图片

尝试对传递的 Authentication 对象进行身份验证,如果成功,则返回完全填充的 Authentication 对象(包括授予的权限)。 AuthenticationManager

必须遵守以下有关异常的约定:

如果帐户被禁用并且 AuthenticationManager 可以测试此状态,则必须抛出 DisabledException。

如果帐户被锁定并且 AuthenticationManager 可以测试帐户锁定,则必须抛出 LockedException。

如果提供了不正确的凭据,则必须抛出 BadCredentialsException。

虽然上述例外是可选的,但 AuthenticationManager 必须始终测试凭据。应测试异常,如果适用,则按上述顺序抛出(即,如果帐户被禁用或锁定,则立即拒绝身份验证请求并且不执行凭据测试过程)。这可以防止针对禁用或锁定的帐户测试凭据。

参数:认证——认证请求对象返回:一个完全认证的对象,包括凭证抛出:AuthenticationException——如果认证失败

AuthenticationManagerBuilder

SecurityBuilder 用来创建一个AuthenticationManager。允许轻松构建内存身份验证、LDAP 身份验证、基于 JDBC 的身份验证、添加 UserDetailsService 和添加 AuthenticationProvider。

SpringSecurity源码解析_第9张图片

重写了AbstractConfiguredSecurityBuilder中performBuild

SpringSecurity源码解析_第10张图片

ProviderManager

是 AuthenticationManager 唯一具体的实现类,主要实现了 AuthenticationManager 接口中的 authenticate

SpringSecurity源码解析_第11张图片

AuthenticationProvider

被 ProviderManager 维护在属性中

SpringSecurity源码解析_第12张图片

主要实现类

SpringSecurity源码解析_第13张图片

第四节

UserDetailsService

SpringSecurity源码解析_第14张图片

DaoAuthenticationProvider

从 UserDetailsService 检索用户详细信息的 AuthenticationProvider 实现

SpringSecurity源码解析_第15张图片

SpringSecurity源码解析_第16张图片

AbstractUserDetailsAuthenticationProvider

SpringSecurity源码解析_第17张图片

重要方法: 

authenticate:实现了 AuthenticationProvider 中的方法 

默认不适用缓存,使用的是 session

SpringSecurity源码解析_第18张图片

认证没有抛出异常

SpringSecurity源码解析_第19张图片

UsernamePasswordAuthenticationFilter

SpringSecurity源码解析_第20张图片

AbstractAuthenticationProcessingFilter

 在 UsernamePasswordAuthenticationFilter 中重写了 attemptAuthentication 方法

SpringSecurity源码解析_第21张图片

SpringSecurity源码解析_第22张图片

FormLoginconfigurer

SpringSecurity源码解析_第23张图片

AbstractAuthenticationFilterConfigurer

 SpringSecurity源码解析_第24张图片

第五节

SecurityContext

定义与当前执行线程关联的最小安全信息的接口。安全上下文存储在SecurityContextHolder中

SpringSecurity源码解析_第25张图片

SecurityContextHolder

将给定的SecurityContext与当前执行线程关联。

此类提供了一系列静态方法,这些方法委托给SecurityContextHolderStrategy的实例

SpringSecurity源码解析_第26张图片

默认策略为 ThreadLocalSecurityContextHolderStrategy

SecurityContextHolderStrategy

针对线程存储安全上下文信息的策略。首选策略由SecurityContextHolder加载。

主要策略:   ThreadLocalSecurityContextHolderStrategy

SpringSecurity源码解析_第27张图片

SecurityContextPersistenceFilter

使用请求之前从配置的SecurityContextRepository获得的信息填充SecurityContextHolder,并在请求完成并清除上下文保持器后将其存储回存储库中。默认情况下,它使用HttpSessionSecurityContextRepository

SecurityContextHolderFilter

使用SecurityContextRepository获取SecurityContext并在SecurityContextHolder上设置它的筛选器。除了SecurityContextRepository之外,这与SecurityContextPersistenceFilter类似。必须显式调用saveContext(SecurityContext、HttpServletRequest、Http ServletResponse)才能保存SecurityContext。这通过允许不同的身份验证机制单独选择是否应该持久化身份验证来提高效率并提供更好的灵活性。

SpringSecurity源码解析_第28张图片

SecurityContextRepository

用于在请求之间持久化SecurityContext的策略。

SpringSecurity源码解析_第29张图片

SpringSecurity源码解析_第30张图片

SecurityContextConfigurer

SpringSecurity源码解析_第31张图片

 SpringSecurity源码解析_第32张图片

第六节

RememberMeAuthenticationFilter

        检测SecurityContext中是否没有Authentication对象,如果RememberMeServices实现请求,则使用remember-me身份验证令牌填充上下文。具体的RememberMeServices实现将有自己的Remember MeServices。此筛选器调用的autoLogin(HttpServletRequest,HttpServletResponse)方法。如果此方法返回一个非空的Authentication对象,它将被传递给AuthenticationManager,以便实现任何特定于身份验证的行为。生成的身份验证(如果成功)将放入SecurityContext中。如果身份验证成功,将向应用程序上下文发布InteractiveAuthenticationSuccessEvent。如果身份验证失败,则不会发布任何事件,因为这通常会通过AuthenticationManager特定的应用程序事件进行记录。通常,无论身份验证成功还是失败,都将允许请求继续

SpringSecurity源码解析_第33张图片

RememberMeAuthenticationProvider

验证RememberMeAuthenticationTokens的AuthenticationProvider实现。

要成功验证,RememberMeAuthenticationToken.getKeyHash()必须匹配此类的getKey()。

SpringSecurity源码解析_第34张图片

RememberMeAuthenticationToken

表示记住的身份验证。记住的身份验证必须提供完全有效的身份验证,包括适用的GrantedAuthority。

SpringSecurity源码解析_第35张图片

RememberMeConfigurer

SpringSecurity源码解析_第36张图片

SpringSecurity源码解析_第37张图片

 SpringSecurity源码解析_第38张图片

RememberMeServices

由能够提供“记住我”服务的类实现。

RememberMeServices 实现的基类:AbstractRememberMeServices

SpringSecurity源码解析_第39张图片

SessionManagementConfigurer

SpringSecurity源码解析_第40张图片

SessionManagementFilter

检测用户自请求开始以来已通过身份验证,如果已通过,则调用配置的SessionAuthenticationStrategy执行任何与会话相关的活动,如激活会话固定保护机制或检查多个并发登录。

SpringSecurity源码解析_第41张图片

SessionAuthenticationStrategy

当身份验证发生时,允许对HttpSession相关行为的可插拔支持。典型的用途是确保会话存在或更改会话Id以防止会话固定攻击。

SpringSecurity源码解析_第42张图片

RegisterSessionAuthenticationStrategy

用于在成功身份验证后向 SessionRegistry 注册用户的策略

ConcurrentSessionControlAuthenticationStrategy

处理并发会话控制的策略。当在身份验证后调用时,它将通过比较用户已激活的会话数和配置的最大会话数值,检查是否允许该用户继续。SessionRegistry用作已验证用户和会话数据的数据源。如果用户已达到允许的最大会话数,则行为取决于exceptionIfMaxExceed属性。默认行为是使超过最大允许会话数的任何会话过期,从最近最少使用的会话开始。如果再次访问,ConcurrentSessionFilter将使过期会话无效。但是,如果exceptionIfMaxExceed设置为true,则将阻止用户启动新的身份验证会话。

SpringSecurity源码解析_第43张图片

CompositeSessionAuthenticationStrategy

 一个SessionAuthenticationStrategy,它接受多个SessionAuthenticationStrategy实现委托给它。每个SessionAuthenticationStrategy都会依次调用。如果抛出任何异常(即SessionAuthenticationException),调用将被短路。

SpringSecurity源码解析_第44张图片

SessionInformation

表示Spring Security框架内会话的记录

SessionRegistry

维护SessionInformation实例的注册表。 唯一实现类 SessionRegistryImpl

SpringSecurity源码解析_第45张图片

SessionInformationExpiredStrategy

确定在 ConcurrentSessionFilter 中检测到过期会话时Concurrent会话筛选器的行为

 ConcurrentSessionFilter SpringSecurity源码解析_第46张图片

第七节

SpringSecurity源码解析_第47张图片

SpringSecurity剩余的除FilterSecurityInterceptor外过滤器,包括但不限于:

AnonymousAuthenticationFilter

检测SecurityContextHolder中是否没有Authentication对象,并在需要时用一个对象填充它。

SpringSecurity源码解析_第48张图片

ExceptionTranslationFilter

处理筛选器链中引发的任何AccessDeniedException和AuthenticationException。这个过滤器是必要的,因为它提供了Java异常和HTTP响应之间的桥梁。它只关心维护用户界面。此筛选器不执行任何实际的安全强制。

SpringSecurity源码解析_第49张图片

LogoutFilter

这一整条链到底如何装配起来了,HttpSecurity到底做了什么?

DelegatingFilterProxy -> FilterChainProxy -> SecurityFilterChain ->具体的Filter

HttpSecurityConfiguration配置了基础的 HttpSecurity对象以供我们注入使用

WebSecurityConfiguration注入了我们自己的 SecurityFilterChain Bean然后添加到WebSecurity中最终由WebSecurity构建出 FilterChainProxy 来执行SpringSecurity的过滤逻辑

九、第九节内容

本节内容将先学习 AuthorizationFilter 这个用于授权的过滤器,与其相对应的还有 FilterSecurityInterceptor。 主要如下类:

AuthorizationFilter

使用AuthorizationManager限制对URL访问的授权筛选器。

SpringSecurity源码解析_第50张图片

AuthorizationManager

一个授权管理器,可以确定身份验证是否可以访问特定对象。

SpringSecurity源码解析_第51张图片

 实现类:RequestMatcherDelegatingAuthorizationManager

SpringSecurity源码解析_第52张图片

实现类AuthenticatedAuthorizationManager

AuthorizationManager,用于确定当前用户是否经过身份验证。

SpringSecurity源码解析_第53张图片

AuthorizationDecision

SpringSecurity源码解析_第54张图片

AuthorizeHttpRequestsConfigurer

SpringSecurity源码解析_第55张图片

RequestAuthorizationContext

HttpServletRequest授权上下文。

SpringSecurity源码解析_第56张图片

AuthorizationManagerRequestMatcherRegistry

AuthorizeHttpRequestsConfigurer 的内部类

SpringSecurity源码解析_第57张图片

AbstractRequestMatcherRegistry

用于注册RequestMatcher的基类。例如,它可能允许指定哪个RequestMatcher需要特定级别的授权。

SpringSecurity源码解析_第58张图片

SpringSecurity源码解析_第59张图片

AuthorizedUrl

AuthorizeHttpRequestsConfigurer 的内部类

允许为RequestMatchers配置AuthorizationManager的对象。

 SpringSecurity源码解析_第60张图片

十、第十节内容

本节内容将攻克SpringSecurity中的终极怪兽,授权处理过滤器FilterSecurityInterceptor。

FilterSecurityInterceptor

通过过滤器实现对HTTP资源执行安全处理。此安全拦截器所需的SecurityMetadataSource的类型为FilterInvocationSecurityMetadaataSource

SpringSecurity源码解析_第61张图片

AbstractSecurityInterceptor

为安全对象实现安全拦截的抽象类

SpringSecurity源码解析_第62张图片

FilterInvocation

保存与HTTP筛选器关联的对象。

SpringSecurity源码解析_第63张图片

ConfigAttribute

SpringSecurity源码解析_第64张图片

SecurityConfig

将ConfigAttribute存储为字符串。

SpringSecurity源码解析_第65张图片

WebExpressionConfigAttribute

用于web请求授权的简单表达式配置属性。

SecurityExpressionHandler

Facade将Spring Security评估安全表达式的要求与底层表达式对象的实现隔离开来

SpringSecurity源码解析_第66张图片

 

AbstractSecurityExpressionHandler

调用内部模板方法来创建StandardEvaluationContext和SecurityExpressionRoot对象。

SpringSecurity源码解析_第67张图片

AbstractInterceptUrlConfigurer

用于配置FilterSecurityInterceptor的基类。

 SpringSecurity源码解析_第68张图片

SpringSecurity源码解析_第69张图片

UrlAuthorizationConfigurer

SpringSecurity源码解析_第70张图片

创建要使用的FilterInvocationSecurityMetadataSource。实现是DefaultFilterInvocationSecurityMetadataSource

ExpressionUrlAuthorizationConfigurer

SpringSecurity源码解析_第71张图片

SpringSecurity源码解析_第72张图片

 SpringSecurity源码解析_第73张图片

SecurityExpressionRoot

 用于Spring Security表达式计算的基本根对象。

SpringSecurity源码解析_第74张图片

子类

SpringSecurity源码解析_第75张图片

AbstractInterceptUrlRegistry

SpringSecurity源码解析_第76张图片

AbstractConfigAttributeRequestMatcherRegistry :用于注册RequestMatcher的基类。例如,它可能允许指定哪个RequestMatcher需要特定级别的授权。

AccessDecisionManager

做出最终访问控制(授权)决定

SpringSecurity源码解析_第77张图片

 实现类:AbstractAccessDecisionManager

SpringSecurity源码解析_第78张图片

AccessDecisionVoter

指示类负责对授权决策进行投票。投票协调(即轮询AccessDecisionVoters、统计他们的响应并做出最终授权决定)由AccessDecisionManager执行。

AffirmativeBased

只有在有拒绝票和没有赞成票的情况下才拒绝访问。如果每个AccessDecisionVoter都弃权,则该决定将基于isAllowIfAllAbstrainDecisions()属性(默认为false)

SpringSecurity源码解析_第79张图片

十一、第十一节内容(实战)

本节内容将讲解SpringSecurity的实战,实现基Token于的访问模式

  • 基于Redis的有状态的Token
  • 基于JWT的无状态Token

十二、第十二节内容(最后一节)

本节内容将讲解SpringSecurity最后一块内容,基于方法级别的权限控制及其实现原理

MethodSecurityInterceptor

SpringSecurity源码解析_第80张图片

MethodInterceptor

PrePostAnnotationSecurityMetadataSource

你可能感兴趣的:(SpringSecurity,java)