SpringSecurity整体架构
Posted 只是六号z
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSecurity整体架构相关的知识,希望对你有一定的参考价值。
Security整体架构
在Spring Security的架构设计中,认证Authentication和授权Authorization是分开的,无论使用什么样的认证方式。都不会影响授权,这是两个独立的存在,这种独立带来的好处之一,就是可以非常方便地整合一些外部的解决方案。
认证
Authentication Manager
在Spring Security中认证是由Authentication Manager接口来负责的,接口定义为:
public interface AuthenticationManager
Authentication authenticate(Authentication var1) throws AuthenticationException;
- 返回Authentication表示认证成功
- 返回Authentication Exception异常,表示认证失败。
Authentication Manager主要实现类为Provider Manager,在Provider Manager中管理了众多Authentication Provider实例。在一次完整的认证流程中,Spring Security 允许存在多个Authentication Provider ,用来实现多种认证方式,这些Authentication Provider都是由Provider Manager 进行统一管理的。
Authentication
认证以及认证成功的信息主要是由Authentication的实现类进行保存的,其接口定义为:
public interface Authentication extends Principal, Serializable
// 获取用户权限信息
Collection<? extends GrantedAuthority> getAuthorities();
//获取用户凭证信息,一般指密码
Object getCredentials();
//获取用户详细信息
Object getDetails();
//获取用户身份信息,用户名、用户对象等
Object getPrincipal();
//用户是否认证成功
boolean isAuthenticated();
//设置认证标记
void setAuthenticated(boolean var1) throws IllegalArgumentException;
SecurityContexHolder
SecurityContextHolderg用来获取登录之后用户信息。Spring Security会将登录用户数据保存在Session 中。但是,为了使用方便,Spring Security在此基础上还做了一些改进,其中最主要的一个变化就是线程绑定。当用户登录成功后,Spring Security 会将登录成功的用户信息保存到SecurityContextHolder中。SecurityContextHolder中的数据保存默认是通过ThreadLocal来实现的,使用ThreadLocal创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是用户数据和请求线程绑定在一起。当登录请求处理完毕后,Spring Security 会将SecurityContextHolder中的数据拿出来保存到Session中,同时将SecurityContexHolder中的数据清空。以后每当有请求到来时,Spring Security就会先从 Session中取出用户登录数据,保存到SecurityContextHolder中,方便在该请求的后续处理过程中使用,同时在请求结束时将SecurityContextHolder中的数据拿出来保存到Session中,然后将Security
SecurityContextHolder中的数据清空。这一策略非常方便用户在Controller、Service层以及任何代码中获取当前登录用户数据。
授权
当完成认证后,接下米就是授权了。在 Spring Securitl 的授权体系中,有两个关键接口,
AccessDecisionManager
AccessDecisionManager(访问决策管理器),用来决定此次访问是否被允许。
AccessDecisionVoter
AccessDecisionVoter(访问决定投票器),投票器会检查用户是否具备应有的角色,进行投出赞成、反对或者是弃权票。
AveasDecisionVoter和 AccessDecisionManager都有众多的实现类,在AccessDecisionManager中会换个遍历AccessDecisionVoter,进而决定是否允许用户访问,因而AveasDecisionVoter和AccessDecisionManager两者的关系类似于AuthenticationProvider和ProviderManager的关系。
ConfigAttribute
configAttribute,用来保存授权时的角色信息。
在Spring security中,用户请求一个资源(通常是一个接口或者一个Java方法)需要的角色会被封装成一个ConfigAttribute对象,在ConfigAttribute 中只有一个getAttribute方法,该方法返回一个Sting字符串,就是角色的名称。一般来说,角色名称都带有一个 ROLE_前缀,投票器AccessDecisionVoter所做的事情,其实就是比较用户所具各的角色和请求某个资源所需的ConfioAutihute之间的关系。
Spring Security源码:配置器详解
文章目录
〇、上篇回顾
- 前面文章介绍了整体架构的设计,知道了整个框架由
建造者
和配置器
构成,而各个建造者在前文也已经了解了,本篇来学学配置器
,了解其内部的组成成员和功能。
一、配置器接口架构
- 整体UML类图
- 展开
SecurityConfigurer
配置器的顶级接口,定义了
init()
和configure()
接口方法
init(B builder)
:初始化@link SecurityBuilder
configure(B builder)
:配置@link SecurityBuilder
必要的属性
SecurityConfigurerAdapter
@link SecurityConfigurer
的子类,init()
和configure()
皆为空实现,由子类去实现。它主要提供了and()
方法,用于获得对正在配置的@link SecurityBuilder
的访问权。
postProcess(T object)
:对传入的对象进行后置处理。and()、getBuilder()
:返回当前正在配置的SecurityBuilder
。
AbstractHttpConfigurer
继承了
SecurityConfigurerAdapter
类,增加了禁用功能,一般自定义配置器时会继承这个类。
disable()
:通过移除@link AbstractHttpConfigurer
来禁用该配置。withObjectPostProcessor
:调用了父类的postProcess(T object)
方法,进行对象的后置处理。
WebSecurityConfigurerAdapter
提供了一个方便的子类来创建
@link WebSecurityConfigurer
实例。该实现允许通过重写方法进行定制。一般我们会继承这个类来定制自己的WebSecurityConfig
。
configure(HttpSecurity http)
:由子类重写这个方法来配置HttpSecurity
建造者。configure(AuthenticationManagerBuilder auth)
:由子类重写这个方法来配置AuthenticationManagerBuilder
建造者。init(final WebSecurity web)
:- 创建
HttpSecurity
对象同时将其保存到securityFilterChainBuilders
中,用于最后真正执行时创建单个的securityFilterChain
。 - 创建一个最后执行的线程,该线程的目的是将过滤器
FilterSecurityInterceptor
添加到WebSecurity
中。
- 创建
public void init(final WebSecurity web) throws Exception
final HttpSecurity http = getHttp();
web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable()
public void run()
FilterSecurityInterceptor securityInterceptor = http
.getSharedObject(FilterSecurityInterceptor.class);
web.securityInterceptor(securityInterceptor);
);
二、如何使用这个框架?
- 其实在开发的时候,
建造者我们是不会动的,我们能做的只是将我们自己的配置添加到整个架构下,所以我们能扩展的是配置器
- 可以参考其他一些源码中默认的配置器,定义我们自己
HttpConfigurer
也继承AbstractHttpConfigurer
,将自定义的单个过滤器配置到HttpSecurity
。 - 可以定义自己的
WebSecurityConfig
配置器,继承WebSecurityConfigurerAdapter
,将源码中默认的一些过滤器和自定义的过滤器配置到HttpSecurity
,由建造者创建后形成一条过滤器链。 - 可以这么理解记忆(但不是很准确)
AbstractHttpConfigurer
配置器是用来配置HttpSecurity
建造者WebSecurityConfigurerAdapter
配置器是用来配置WebSecurity
建造者
三、总结
- 其实整个配置器最重要的两个方法就是
init()
和configure()
,目的是配置WebSecurity
、HttpSecurity
和AuthenticationManagerBuilder
三个建造者,所有都配置好后就可以创建核心过滤器了。 AbstractHttpConfigurer
配置器是用来配置HttpSecurity
建造者WebSecurityConfigurerAdapter
配置器是用来配置WebSecurity
建造者
四、系列文章
Spring Security 系列
- 《手把手教你如何使用Spring Security(上):登录授权》
- 《手把手教你如何使用Spring Security(中):接口认证》
- 《手把手教你如何使用Spring Security(下):访问控制》
- 《Spring Security源码(一):整体框架设计》
- 《Spring Security源码(二):建造者详解》
- 《Spring Security源码(三):HttpSecurity详解》
- 《Spring Security源码(四):配置器详解》
- 《Spring Security源码(五):FilterChainProxy是如何创建的?》
- 《Spring Security源码(六):FilterChainProxy是如何运行的?》
- 《Spring Security源码(七):设计模式在框架中的应用》
- 《Spring Security源码(八):登录认证源码流程》
- 《Spring Security源码(九):过滤器链上的过滤器是如何排序的?》
- 《Spring Security源码(十):权限访问控制是如何做到的?》
Spring Security OAuth 系列
以上是关于SpringSecurity整体架构的主要内容,如果未能解决你的问题,请参考以下文章
安全框架Spring Security是什么?如何理解Spring Security的权限管理?
SpringCloud微服务安全网关安全 3-2 常见的微服务安全整体架构
Java 安全框架Apache Shiro学习入门(Shiro 架构及其组件)