本文主要是介绍Spring Security 框架结构知识(持续更新),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概述
Spring Security 是一款安全管理框架,在SpringBoot/SpringCloud环境下可以达成0配置的方式集成,非常方便
大致模型
DelegatingFilterProxy
Spring提供了一个名为DelegatingFilterProxy的过滤器实现,它允许在Servlet容器的生命周期和Spring的ApplicationContext之间架桥
FilterChainProxy
这是Spring Security提供的过滤器链代理,它被包含在DelegatingFilterProxy
过滤器中,在接受请求时会经由FilterChainProxy
决定来使用哪一条SecurityFilterChain
过滤器链
SecurityFilterChain
这个是由FilterChainProxy
代理来决定实例的调用,这样对每一套匹配我们都可以有细致的配置,其中SecurityFilterChain
实例下的SecurityFilter
一般都是Bean
在过滤器链代理对象中可以有一个或多个过滤器链,在多个过滤器链中一个请求会匹配首个满足匹配条件的过滤器链
默认Chain下的Filter
- ChannelProcessingFilter:确保web请求通过通道的过滤器
- ConcurrentSessionFilter:并发会话处理包所需的过滤器,这个过滤器会进行两个操作,一是为每个请求设置最后一次请求事件,二是检索回话信息检查回话是否被标识为已过时,如果过时则会使其失效
- WebAsyncManagerIntegrationFilter:填充
SecurityContext
的过滤器 - SecurityContextPersistenceFilter:请求处理前从
SecurityContextRepository
获取SecurityContext
并在请求结束后清除此SecurityContext
- HeaderWriterFilter:为请求添加一些头部信息的过滤器
- CsrfFilter:使用同步器令牌模式应用CSRF保护,开发人员需要确保对任何允许状态更改的请求调用
CsrfFilter
- LogoutFilter:用户退出的过滤器,他会顺序的调用
LogoutSuccessHandler
和LogoutHandler
- OAuth2AuthorizationRequestRedirectFilter:此过滤器通过将最终用户的用户代理重定向到授权服务器的授权端点来启动授权代码授予
- Saml2WebSsoAuthenticationRequestFilter:不知道是什么用
- X509AuthenticationFilter:支持X509身份验证的过滤器
- AbstractPreAuthenticatedProcessingFilter:预处理过滤器,对身份验证的预先处理,默认情况下如果认证失败任然会继续下一个过滤器
- CasAuthenticationFilter:不知道
- OAuth2LoginAuthenticationFilter:用于OAuth 2.0登录的过滤器实现
- Saml2WebSsoAuthenticationFilter:不知道
- UsernamePasswordAuthenticationFilter:处理表单提交的身份验证,默认需要两个参数(username和password)进行身份验证,这个过滤器默认响应于请求
/login
URL的请求 - OpenIDAuthenticationFilter:处理OpenID身份验证请求的过滤器
- DefaultLoginPageGeneratingFilter:在用户没有配置登录页面时将会插入到过滤器链的过滤器,提供了默认登录页面配置等等
- DefaultLogoutPageGeneratingFilter:构建一个默认的退出登录页面配置的过滤器
- DigestAuthenticationFilter:处理摘要身份验证的处理器
- BearerTokenAuthenticationFilter:认证包含OAuth 2.0承载令牌的请求,此过滤器应该被写入
AuthenticationManager
并BearerTokenAuthenticationToken
能被AuthenticationManager
验证 - BasicAuthenticationFilter:基于Basic的身份验证过滤器
- RequestCacheAwareFilter:如果缓存了一个与当前请求匹配的请求对象,负责重新构造所缓存的请求,它将会调用配置的
RequestCache
上的getMatchingRequest ()
,如果方法返回一个增强的request
则会将它交给doFilter()
,如果方法返回null
将使用原始的请求,过滤器是没有效果的 - SecurityContextHolderAwareRequestFilter:对请求对象进行包装增强的过滤器,这个过滤器为请求扩展了以下几个方法
HttpServletRequest.authenticate(HttpServletResponse)
:允许用户确定他们是否经过身份验证,如果没有则将用户发送到登录页面HttpServletRequest.login(String, String)
:允许用户通过AuthenticationManager
进行身份验证HttpServletRequest.logout()
:允许使用配置的LogoutHandler
进行注销AsyncContext.start(Runnable)
:自动的复制从当前线程的SecurityContextHolder
找到的SecurityContext
到Runable
线程
- JaasApiIntegrationFilter:试图获取JAAS Subject并继续作为该Subject运行的过滤器
- RememberMeAuthenticationFilter:检测
SecurityContext
中是否没有Authentication
对象,如果RememberMeServices
有被实现,则将Authentication
填充到SecurityContext
中,通过过滤器调用RememberMeServices
的autoLogin()
方法,如果该方法返回一个非空Authentication
对象则会把此对象传递给AuthenticationManager
- AnonymousAuthenticationFilter:检测
SecurityContext
中是否没有Authentication
对象,并在需要时填充一个,默认实现是在没有Authentication
对象时创建一个匿名的Authentication
对象放入到SecurityContext
中 - OAuth2AuthorizationCodeGrantFilter:OAuth 2.0授权代码授予的过滤器,它处理OAuth 2.0授权响应的处理
- SessionManagementFilter:检测用户自请求开始以来已经通过身份验证,如果已经通过,则调用配置的
SessionAuthenticationStrategy
来执行任何与会话相关的活动 - ExceptionTranslationFilter:处理在过滤器链中抛出的任何
AccessDeniedException
和AuthenticationException
异常 - FilterSecurityInterceptor:通过过滤器实现执行HTTP资源的安全处理
- SwitchUserFilter:切换用户处理过滤器负责用户上下文切换
Security Filters
这个是过滤器链中的具体过滤器,经由SecurityFilterChain
来进行注册
Authentication 认证
Spring Security 提供了全面的身份验证功能
以下是基于servlet应用会用到的一些组件
- SecurityContextHolder:SecurityContextHolder是Spring Security身份验证的地方
- SecurityContext:是从
SecurityContextHolder
获取且包含当前已认证用户的Authentication
对象信息的组件 - Authentication:可以被输入到
AuthenticationManager
中去提供给认证一个用户或则认证当前用户 - GrantedAuthority:在认证过程中授予主体(用户)的权限组件
- AuthenticationManager:定义Spring Security的过滤器如何执行身份验证的API
- ProviderManager:AuthenticationManager最常见的实现
- AuthenticationProvider:由ProviderManager用于执行特定类型的身份验证
- Request Credentials with AuthenticationEntryPoint:用于从客户端请求凭据
- AbstractAuthenticationProcessingFilter:用于身份验证的基本过滤器
SecurityContextHolder
SecurityContextHolder
是SecurityContext
的获取器,他可以获取、创建SecurityContext
默认的情况下SecurityContextHolder
是使用一个ThreadLocal
来储存这些细节,这就意味着SecurityContextHolder
只会在同一线程下的方法中可用,但我们也可以通过设置来改变这个默认模式
SecurityContext
这个SecurityContext
是从SecurityContextHolder
获取得到的,SecurityContext
包含着Authentication
认证信息对象
Authentication
这个Authentication
主要用于以下两个用途
- 作为
AuthenticationManager
的输入,提供用户所提供的身份验证的凭证,此时用户是未认证的,自然isAuthenticated()
是false
- 代表当前已经认证的用户,当前这个
Authentication
是可以通过SecurityContext
获取得到
这个Authentication主要包含了
- principal:识别用户,当使用用户名/密码进行身份验证时,这通常是
UserDetails
的一个实例 - credentials:通常代表一个密码,在用户通过认证且保证不泄露的情况下通常会被清除掉
- authorities:赋予用户的权限
GrantedAuthority
GrantedAuthority
是给用户赋予的权限,例如角色、范围等
GrantedAuthority
可以从Authentication.getAuthorities()
方法中获得
AuthenticationManager
AuthenticationManager
是定义Spring Security的过滤器如何执行身份验证的API
ProviderManager
ProviderManager
是最常用的AuthenticationManager
实现方式,ProviderManager
代表一个AuthenticationProvider
的集合,其中每一个AuthenticationProvider
都有机会去决定身份验证是否成功、失败、或则不下决定而交给下游的AuthenticationProvider
做决定,如果配置的AuthenticationProvider
都不能够作出决定那么将会抛出AuthenticationException
异常,代表不能处理这种身份验证
在AuthenticationProvider
的集合中,每一个AuthenticationProvider
都可以处理不同类型的身份验证,例如第一个处理的是用户名/密码,第二个处理的是SAML,他们互不影响
我们可以为ProviderManager
配置一个父AuthenticationManager
,在自身没有可处理的AuthenticationProvider
时候,将会去请求这个父AuthenticationProvider
管理器,通常这个是一个ProviderManager
实例
- 对返回的
Authentication
进行拷贝加入缓存,保留用户凭着 - 禁用
ProviderManager
的eraseCredentialsAfterAuthentication
属性,保留凭着
AuthenticationProvider
我们可以将多个AuthenticationProvider
注入到ProviderManager
中,每一个AuthenticationProvider
都执行特定类型的认证
AuthenticationEntryPoint
AuthenticationEntryPoint
用于发送从客户端请求凭据的HTTP响应
AbstractAuthenticationProcessingFilter
AbstractAuthenticationProcessingFilter
是用于验证用户凭证的基本Filter
,在认证凭证之前,Spring Security通常使用AuthenticationEntryPoint
请求凭证
大体的执行流程
- 当用户提交凭证,这个
AbstractAuthenticationProcessingFilter
将通过HttpServletRequest
创建一个Authentication
对象用于身份验证,这个Authentication
的类型依赖于AbstractAuthenticationProcessingFilter
的子类 Authentication
传递给AuthenticationManager
进行身份验证- 如果验证失败
- 这个
SecurityContextHolder
会被清除 RememberMeServices.loginFail
将会被调用,如果有配置的话AuthenticationFailureHandler
被调用
- 这个
- 如果验证成功
SessionAuthenticationStrategy
收到新登录的通知- 这个
Authentication
设置在SecurityContextHolder
中,随后,SecurityContextPersistenceFilter
将SecurityContext
保存到HttpSession
RememberMeServices.loginSuccess
将被调用,如果有配置的话ApplicationEventPublisher
触发一个InteractiveAuthenticationSuccessEvent
事件
用户名/密码认证
用户名/密码是最为常见的身份验证方式,Spring Security为此提供和非常广泛的支持
Spring Security提供了以下内置机制,用于从HttpServletRequest
读取用户名和密码
表单登录
Spring Security可以通过表单中的内容获取登录所需的用户名密码,在没有任何配置的情况下是默认打开的,但是如果有任何servlet配置的情况下需要手动指定
protected void configure(HttpSecurity http) {// 配置http.formLogin(withDefaults());
}
对于默认HTML表单提交配置我们需要注意几点:1.表单应该以post提交方式进行认证
2.表单应该指明username参数为用户名
2.表单应该指明password参数为密码
Authorization 授权
权限对象由一个GrantedAuthority
接口表示,权限对象由AuthenticationManager
插入到Authentication
对象中,然后由AccessDecisionManager s
在进行授权决策时读取
这篇关于Spring Security 框架结构知识(持续更新)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!