整理中…
一、Spring Security 工作原理简介
单个 HTTP 请求的过程中,通过 FilterChain 拦截并处理请求和响应:
Spring Security 就是基于 Filter 来实现的。
DelegatingFilterProxy 是 Spring 基于 Servlet Filter 标准实现的一个 Filter ,目的是 1. 通过Spring容器来管理 Servlet Filter 的生命周期;2.通过 DelegatingFilterProxy 注册 Spring 的 Bean。
Spring Security Filter 的入口是 FilterChainProxy(FilterChainProxy 是 Spring 的一个 Bean),FilterChainProxy 使用 SecurityFilterChain 来确定应该为一个请求调用哪些 Spring Security Filters。

二、Spring Security Authentication
2.1. Authentication(Spring Security 的身份验证)
Architecture components(用于 Servlet 身份验证的 SpringSecurity 的主要架构组件)
- SecurityContextHolder:Spring Security 存储身份验证人员详细信息的地方;
- SecurityContext:从 SecurityContextHolder 获得并包含当前身份验证的用户的身份验证;
- Authentication:可以是 AuthenticationManager 的输入,以提供用户提供的用于身份验证的凭据或来自 SecurityContext 的当前用户;
- GrantedAuthority:授予主体身份验证的权限(角色、范围等)
- AuthenticationManager:定义 Spring Security 的过滤器如何执行身份验证的 API;
- ProviderManager:AuthenticationManager 最常见的实现;
- AuthenticationProvider:ProviderManager 使用它来执行特定类型的身份验证;
- Request Credentials with AuthenticationEntryPoint:用于从客户端请求凭据(即重定向到登录页面、发送 WWW-Authenticate 响应等)
- AbstractAuthenticationProcessingFilter:用于身份验证的基本过滤器(这也很好地了解了高级身份验证流程以及各个部分如何协同工作)。

AuthenticationManager、ProviderManager、AuthenticationProvider 之间的关系:


2.2.Authentication Mechanisms(认证机制)
- Username and Password
- OAuth 2.0 Login
- SAML 2.0 Login
- Central Authentication Server (CAS)
- Remember Me
- JAAS Authentication
- OpenID
- Pre-Authentication Scenarios
- X509 Authentication
2.3. Security Filters
Spring Security Filter 完整顺序及使用场景:
参考文章:不掌握这些内置Filter 你就学不会 Spring Security
- ChannelProcessingFilter:访问控制协议过滤器。通常用来过滤哪些请求必须用 https 协议,哪些请求必须用 http 协议,哪些请求随便用哪个协议都行。通过 HttpSecurity#requiresChannel() 配置
- WebAsyncManagerIntegrationFilter:用来处理异步请求的安全上下文。用于集成 SecurityContext 到 Spring 异步执行机制中的 WebAsyncManager。
具体逻辑为:
- 从请求属性上获取所绑定的 WebAsyncManager,如果尚未绑定,先做绑定;
- 从 asyncManager 中获取 key 为 CALLBLE_INTERCEPTOR_KEY 的安全上下文多线程处理器 SecurityContextCallableProcessingInterceptor,如果获取到的为 null,新建一个 SecurityContextCallableProcessingInterceptor 并绑定 CALLABLE_INTERCEPTOR_KEY 注册到 asyncManager 中。
- 通过 WebSecurityConfigurerAdapter#getHttp() 方法添加到 HttpSecurity 中成为 DefaultSecurityFilterChain 的一个链节。
- SecurityContextPersistenceFilter:用来创建一个 SecurityContext 并存储到 SecurityContextHolder 中,在请求结束后。主要控制 SecurityContext 在一次请求中的生命周期。请求来临时,创建 SecurityContext 安全上下文信息,请求结束时将 SecurityContext 存储在 HttpSession 中,并清空。
通过 HttpSecurity#securityContext() 及相关方法引入其配置对象 SecurityContextConfigurer 来进行配置。 - HeaderWriterFilter:用来给 Http 响应添加一些 Header ,比如 X-Frame-Options,X-XSS-Protection,X-Content-Type-Options。
通过 HttpSecurity#headers() 来定制请求 Header。 - CorsFilter:跨域相关的过滤器。这是 SpringMVC Java 配置额 XML 命名空间 CORS 配置的替代方法,仅对依赖于 spring-web 的应用程序有用(不适用于 spring-webmvc)或要求在 javax.servlet.Filter 级别进行 CORS 检查的安全约束链接。
通过 HttpSecurity#cors() 来定制。 - CsrfFilter:用于防止 csrf 攻击,前后端使用 json 交互需要注意的一个问题。。
可以通过 HttpSecurity.csrf() 来开启或关闭它。在使用 jwt 或 token 技术时,是不需要这个的。 - LogoutFilter:注销的过滤器。可以通过 HttpSecurity.logout() 来定制注销逻辑,非常有用。
- OAuth2AuthorizationRequestRedirectFilter:需要依赖 spring-security-oauth2 相关的模块。该过滤器是处理 OAuth2 请求首选重定向相关逻辑的。
- Saml2WebSsoAuthenticationRequestFilter:需要用到 Spring Security SAML 模块,是一个基于 SAML 的SSO 单点登录请求认证过滤器。
关于SAML
SAML 即安全断言标记语言,英文全称是 Security Assertion Markup Language。它是一个基于 XML 的标准,用于在不同的安全域(security domain)之间交换认证和授权数据。在 SAML 标准定义了身份提供者 (identity provider) 和服务提供者 (service provider),这两者构成了前面所说的不同的安全域。 SAML 是 OASIS 组织安全服务技术委员会(Security Services Technical Committee) 的产品。
SAML(Security Assertion Markup Language)是一个 XML 框架,也就是一组协议,可以用来传输安全声明。比如,两台远程机器之间要通讯,为了保证安全,我们可以采用加密等措施,也可以采用 SAML 来传输,传输的数据以 XML 形式,符合 SAML 规范,这样我们就可以不要求两台机器采用什么样的系统,只要求能理解 SAML 规范即可,显然比传统的方式更好。SAML 规范是一组 Schema 定义。
可以这么说,在Web Service 领域,schema 就是规范,在 Java 领域,API 就是规范
- X509AuthenticationFilter:X509 认证过滤器。可以通过 HttpSecurity#X509() 来启用和配置相关功能。
- AbstractPreAuthenticatedProcessingFilter:处理经过预先认证的身份验证请求的过滤器的基类,其中认证主体已经由外部系统进行了身份验证。目的只是从传入请求中提取主体上的必要信息,而不是对它们进行身份验证。可以继承该类进行具体实现并通过 HttpSecurity#addFilter 方法来添加个性化的 AbstractPreAuthenticatedProcessingFilter。
- CasAuththenticationFilter:CAS 单点登录认证过滤器。依赖 Spring Security CAS 模块。
- OAuth2LoginAuthenticationFilter:需要依赖 spring-security-oauth2 相关的模块。 OAuth2 登录认证过滤器。处理通过 OAuth2 进行认证登录的逻辑。
- SamlWebSsoAuthentication:需要用到 Spring Security SAML 模块,这是一个基于 SAML 的 SSO 单点登录认证过滤器。
- UsernamePasswordAuthenticationFilter:处理用户以及密码认证的核心过滤器。认证请求提交的 username 和 password ,被封装成 token 进行一系列的认证,主要是通过这个过滤器完成的,在表单认证的方法中,这是最关键的过滤器。
- OpenIDAuthenticationFilter:基于 OpenID 认证协议的认证过滤器,需要在依赖中依赖额外的相关模块才能启用它。
- DefaultLoginPageGeneratingFilter:生成默认的登录页。默认 /login
- DefaultLogoutPageGeneratingFilter:生成默认的退出页。默认 /logout
- ConcurrentSessionFilter:并发访问控制过滤器,主要用来判断 session 是否过期以及更新最新的访问时间。
其流程为:
- session 检测,如果不存在直接放行取执行下一个过滤器。存在则进行下一步;
- 根据 sessionId 从 SessionRegistry 中获取 SessionInformation,从 SessionInformation 中获取 session 是否过期;没有过期则更新 SessionInformation 中的访问日期;如果过期,则执行 doLogout() 方法,这个方法会将 session 无效,并将 SecurityContext 中的 Authentication 中的权限置空,同时在 SecurityContextHolder 中清除 SecurityContext,然后查看是否有跳转的 expiredUrl,如果有就跳转,没有就输出提示信息。
- ConcurrentSessionFilter 通过 SessionManagementConfigurer 来进行配置。
- DigestAuthenticationFilter:Digest 身份验证是 Web 应用程序中流行的可选的身份验证机制。DigestAuthenticationFilter n能够处理 HTTP 头中显示的摘要式身份验证凭据。可以通过 HttpSecurity#addFilter() 来启用和配置相关功能。
- BearerTokenAuthenticationFilter:
- BasicAuthenticationFilter:和Digest身份验证一样都是Web 应用程序中流行的可选的身份验证机制 。 BasicAuthenticationFilter 负责处理 HTTP 头中显示的基本身份验证凭据。这个 Spring Security 的 Spring Boot 自动配置默认是启用的 。
BasicAuthenticationFilter 通过 HttpSecurity#httpBasic() 及相关方法引入其配置对象 HttpBasicConfigurer 来进行配置。 - RequestCacheAwareFilter:用于用户认证成功后,重新恢复因为登录被打断的请求。当匿名访问一个需要授权的资源时。会跳转到认证处理逻辑,此时请求被缓存。在认证逻辑处理完毕后,从缓存中获取最开始的资源请求进行再次请求。
RequestCacheAwareFilter 通过 HttpScurity#requestCache() 及相关方法引入其配置对象 RequestCacheConfigurer 来进行配置。 - SercurityContextHolderAwareRequestFilter:将 ServletRequest 封装。用来 实现j2ee中 Servlet Api 一些接口方法, 比如 getRemoteUser 方法、isUserInRole 方法,在使用 Spring Security 时其实就是通过这个过滤器来实现的。
SecurityContextHolderAwareRequestFilter 通过 HttpSecurity.servletApi() 及相关方法引入其配置对象 ServletApiConfigurer 来进行配置。 - JaasApiIntegrationFilter:适用于JAAS (Java 认证授权服务)。如果 SecurityContextHolder 中拥有的 Authentication 是一个 JaasAuthenticationToken,那么该 JaasApiIntegrationFilter 将使用包含在 JaasAuthenticationToken 中的 Subject 继续执行 FilterChain。
- RemeberMeAuthenticationFilter:处理 记住我 功能的过滤器。
RememberMeAuthenticationFilter 通过 HttpSecurity.rememberMe() 及相关方法引入其配置对象 RememberMeConfigurer 来进行配置。 - AnonymousAuthenticationFilter:匿名认证过滤器。对于 Spring Security 来说,所有对资源的访问都是有 Authentication 的。对于无需登录(UsernamePasswordAuthenticationFilter )直接可以访问的资源,会授予其匿名用户身份。
AnonymousAuthenticationFilter 通过 HttpSecurity.anonymous() 及相关方法引入其配置对象 AnonymousConfigurer 来进行配置。 - OAuth2AuthorizationCodeGrantFilter:
- SessionManagementFilter:Session 管理器过滤器,内部维护了一个 SessionAuthenticationStrategy 用于管理 Session 。
SessionManagementFilter 通过 HttpScurity#sessionManagement() 及相关方法引入其配置对象 SessionManagementConfigurer 来进行配置。 - ExceptionTranslationFilter:主要来传输异常事件,还记得之前我们见过的 DefaultAuthenticationEventPublisher 吗?
- FilterSecurityInterceptor:这个过滤器决定了访问特定路径应该具备的权限,访问的用户的角色,权限是什么?访问的路径需要什么样的角色和权限?这些判断和处理都是由该类进行的。如果你要实现动态权限控制就必须研究该类 。
- AuthorizationFilter:
- SwitchUserFilter:SwitchUserFilter 是用来做账户切换的。默认的切换账号的url为/login/impersonate,默认注销切换账号的url为/logout/impersonate,默认的账号参数为username 。
可以通过此类实现自定义的账户切换。
















