文章目录
- 1. SecurityContextHolder 上下文持有器
- 2. ConfigAttribute 存储与安全系统相关的配置属性
- 3. GrantedAuthority 权限封装类
- 4. RoleHierarchy 角色层次结构获取
- 5. AuthenticatedPrincipal 获取主体属性
- 6. ObjectPostProcessor 对象初始化
- 7.Authentication 认证
- 7.1 ClientRegistration 客户端注册OAuth 2.0或OpenID Connect 1.0提供者的表示。
- 7.2 OAuth2Token OAuth2秘钥
- 7.3 Authentication 身份验证主体的令牌
- 7.4 UserDerails 核心用户信息
- 7.5 AuthenticationManager 认证管理器
- 7.6 UserCache UserDetails对象的缓存
- 7.7 UserDetailsService 加载用户特定数据的核心接口
- 7.8 AuthenticationProvider
- 7.9 AbstractOAuth2AuthorizationGrantRequest 授权请求
- 7.10 OAuth2UserService 从UserInfo端点获取终端用户属性
- 7.11 GrantedAuthoritiesMapper 加载权限的mapper
- 7.12 UserDetailsChecker 用户信息检查
- 8.鉴权
1. SecurityContextHolder 上下文持有器
内部封装一个SecurityContextHolderStrategy(一种针对线程存储安全上下文信息的策略),通过配置文件初始化对应的策略,以达到获取和设置上下文的目的(SecurityContext)
1.1 SecurityContextHolderStrategy 针对线程存储安全上下文信息的策略

- ThreadLocalSecurityContextHolderStrategy:利用
ThreadLocal来存储一个SecurityContext - InheritableThreadLocalSecurityContextHolderStrategy:利用
InheritableThreadLocal来存储SecurityContext,InheritableThreadLocal和ThreadLocal的区别在于子线程获取出来的内容和父线程的一致。即可以在父线程和子线程中传递参数。 - GlobalSecurityContextHolderStrategy:全局策略,维护一个全局的
SecurityContext变量,不安全,不推荐使用。 - ListeningSecurityContextHolderStrategy:内部封装一个
SecurityContextHolderStrategy变量,保存SecurityContext也是保存在这个变量中。在这个基础上还封装了SecurityContextChangedListener集合,在调用clearContext和setContext方法时会调用SecurityContextChangedListener的方法进行消息发布、通知
1.2 SecurityContextChangedListener 上下文变更监听器

这是一个函数式接口,Spring Security并没有提供实现类,用户可以根据需求进行扩展。
1.3 SecurityContext 接口定义与当前执行线程关联的最小安全信息。

这个接口主要是封装Authentication并有get、set方法的上下文
2. ConfigAttribute 存储与安全系统相关的配置属性

-
ConfigAttribute:只有一个getAttribute方法,返回值为String -
SecurityConfig: 将ConfigAttribute存储为字符串。并提供这个字符串的获取方法等 -
Jsr250SecurityConfig:适用于JSR 250注释属性的安全配置。/** * Security config applicable as a JSR 250 annotation attribute. * * * <pre> * * 适用于JSR 250注释属性的安全配置。 * </pre> * @author Ryan Heaton * @since 2.0 */ public class Jsr250SecurityConfig extends SecurityConfig { public static final Jsr250SecurityConfig PERMIT_ALL_ATTRIBUTE = new Jsr250SecurityConfig(PermitAll.class.getName()); public static final Jsr250SecurityConfig DENY_ALL_ATTRIBUTE = new Jsr250SecurityConfig(DenyAll.class.getName()); public Jsr250SecurityConfig(String role) { super(role); } } -
PostInvocationAttribute和PreInvocationAttribute两个接口都没有任何属性,分别是@PostFilter和@PostAuthorize注解、@PreFilter和@PreAuthorize注解创建的属性的标记接口 -
AbstractExpressionBasedMethodConfigAttribute:包含过滤和授权表达式元数据,用于基于Spring-EL的访问控制。用于方法调用前或后调用阶段的基类。过滤器或授权表达式可以为空,但不能同时为空。注意:这个类虽然重写了父类的getAttribute方法,但固定返回null,即没有使用这个方法。 -
PreInvocationExpressionAttribute:继承父类方法的同时内部封装了一个
filterTarget字符串。 -
PostInvocationExpressionAttribute:重写了
toString方法
3. GrantedAuthority 权限封装类

- GrantedAuthority:只有一个
getAuthority方法,可以获取权限字符串 - SwitchUserGrantedAuthority:内部封装一个
role字符串和一个Authentication对象 - JaasGrantedAuthority:内部封装一个
role字符串和一个Principal对象 - SimpleGrantedAuthority:内部封装一个
role字符串 - OAuth2UserAuthority:可能与OAuth2User相关联的GrantedAuthority。内部封装一个权限字符串和一个属性map
- OidcUserAuthority:可能与一个OidcUser相关联的GrantedAuthority。在父类的基础上封装一个
OidcIdToken和一个OidcUserInfo
4. RoleHierarchy 角色层次结构获取

该类定义了用于各种访问检查组件的角色层次结构,层次定义是使用 > 符号进行定义,例如:
//意思是Student权限拥有Study权限,Study权限拥有English权限,English权限拥有Paragraph权限,推理得,如果一个人有Student这个角色,那他同时就拥有了Student、Study、English、Paragraph权限
"Student > Study > English > Paragraph"
- RoleHierarchy:接口定义获取从属权限的方法,即传入一个授权集合,返回这个授权集合的所有从属权限。
- NullRoleHierarchy:什么都不干,传入什么就返回什么。
- RoleHierarchyImpl:利用 > 符号进行权限风格,定义从属关系(层级结构),即上面讲到的结构。
5. AuthenticatedPrincipal 获取主体属性

- AuthenticatedPrincipal:接口只提供一个获取主体名称的方法。
public interface AuthenticatedPrincipal {
/**
* Returns the name of the authenticated <code>Principal</code>. Never
* <code>null</code>.
*
* <p>
* 返回经过身份验证的主体的名称。 不为空。
* </p>
* @return the name of the authenticated <code>Principal</code>
*/
String getName();
}
- Saml2AuthenticatedPrincipal:
AuthenticatedPrincipal的Saml2表示。这个接口提供了四个默认方法,具体的逻辑交给子类实现。 - DefaultSaml2AuthenticatedPrincipal:
Saml2AuthenticatedPrincipal的默认实现,封装name、attributes和registrationId - OAuth2AuthenticatedPrincipal:与OAuth 2.0令牌关联的主体,接口可以获取token属性、权限集合等。
- OAuth2User:在OAuth 2.0提供者中注册的用户主体的表示形式
- DefaultOAuth2User: OAuth2User的默认实现。除了获取主体名称以外,还提供了属性Map、权限集合、以及在属性Map中对应主体名称的key(以便
getName方法获取name) - OidcUser:使用OpenID Connect 1.0提供程序注册的用户主体的表示形式。在父类的基础上提供
getClaims、getUserInfo、getIdToken三个方法 - DefaultOidcUser:
OidcUser的默认实现。封装OidcIdToken和OidcUserInfo - DefaultOAuth2AuthenticatedPrincipal:包装OAuth 2.0令牌属性的域对象。封装token属性、权限集合、主体名称。
- OAuth2IntrospectionAuthenticatedPrincipal:内部封装一个
DefaultOAuth2AuthenticatedPrincipal,所有操作都是基于这个DefaultOAuth2AuthenticatedPrincipal
6. ObjectPostProcessor 对象初始化

- ObjectPostProcessor:允许初始化对象。 通常,这用于调用Aware方法。InitializingBean.afterPropertiesSet(),并确保调用了DisposableBean.destroy()。
- AutowireBeanFactoryObjectPostProcessor: 允许注册对象来参与AutowireCapableBeanFactory对Aware方法、InitializingBean.afterPropertiesSet()和DisposableBean.destroy()的后处理。
- CompositeObjectPostProcessor:组合模式,内部封装了ObjectPostProcessor集合,遍历执行集合里每一个
ObjectPostProcessor的postProcess方法。
7.Authentication 认证
7.1 ClientRegistration 客户端注册OAuth 2.0或OpenID Connect 1.0提供者的表示。
这个类封装了很多Oauth2使用的信息,例如scope、clientId、clientSecret等等
7.2 OAuth2Token OAuth2秘钥

- OAuth2Token:提供获取token、过期时间、令牌发出时间等属性获取接口
- AbstractOAuth2Token:对
OAuth2Token的实现 - OAuth2AccessToken:用户的访问令牌,包括
token的值和scope列表 - OAuth2RefreshToken:
token刷新令牌 - OidcIdToken:
OidcIdToken是一个安全令牌,它包含关于授权服务器对终端用户进行身份验证的“claims”。
7.3 Authentication 身份验证主体的令牌

这个类及其下属类是各个令牌的表现方式,大多都只是针对不同功能简单的封装不同的参数
7.4 UserDerails 核心用户信息

UserDetails提供用户的核心信息,其中User类是最基础的,里面封装了用户的各个信息。而MutableUser的内部封装了一个UserDetails和一个password,操作都是基于内部分UserDetails,为什么在这个类里面单独封装一个password呢?可能是因为User类实现了CredentialsContainer接口,而这个接口是为了删除敏感数据,因此在User类中将password置空了。而这个类单独封装一个password和一个UserDetails就既可以保存password也可以实现去除敏感数据
7.5 AuthenticationManager 认证管理器

AuthenticationManager提供认证方法,传入Authentication类,如果认证成功,则返回一个完全填充的Authentication,不成功则返回null
- NoOpAuthenticationManager:这是
AbstractSecurityInterceptor的内部类,调用这个类的authenticate方法直接抛错 - ResolvingAuthenticationManager:这是
JwtIssuerAuthenticationManagerResolver的内部类,是针对BearerTokenAuthenticationToken的一个AuthenticationManager,主要逻辑是从token中取出issuer,再通过AuthenticationManagerResolver解析出authenticationManager并利用这个authenticationManager进行认证 - ProviderManager:内部封装一个
AuthenticationProvider集合和一个AuthenticationManager作为父管理器,先迭代判断每一个AuthenticationProvider,如果有认证成功的,返回完整信息,如果都不成功并且抛出的是AuthenticationException,那么会执行父管理器的authenticate方法判断认证是否成功。
7.6 UserCache UserDetails对象的缓存

- SpringCacheBasedUserCache:利用spring自带的
cache来完成UserDetails的缓存 - NullUserCache:什么都没做
7.7 UserDetailsService 加载用户特定数据的核心接口

- UserDetailsPasswordService:用于修改
UserDetails密码的API。 - UserDetailsManager:提供
创建用户、修改用户、删除用户、修改密码、判断用户是否存在等方法的接口 - InMemoryUserDetailsManager:
UserDetailsManager的非持久实现,它是由一个内存映射支持的测试类,一般生产并不使用这个 - ReactiveUserDetailsServiceAdapter:
WithUserDetailsSecurityContextFactory的内部类,内部封装一个ReactiveUserDetailsService - CachingUserDetailsService:基于
UserCache实现UserDetails存储。 - UserDetailsServiceImpl:内部封装一个
UserRepository - JdbcDaoImpl:使用
JDBC查询从数据库中检索用户详细信息(用户名、密码、启用标志和权限)。
7.8 AuthenticationProvider
7.9 AbstractOAuth2AuthorizationGrantRequest 授权请求

OAuth 2.0权限授予请求的基本实现,该请求持有权限授予凭据,并在向授权服务器的令牌端点发起请求时使用。可以理解为我们向controller层请求的request请求。这个类的子类要分两部分来理解。
- 第一类:请求类,
OAuth2PasswordGrantRequest、、OAuth2ClientCredentialsGrantRequest、OAuth2AuthorizationCodeGrantRequest、JwtBearerGrantRequest、OAuth2RefreshTokenGrantRequest,前三个类分别是密码模式(password)、客户端模式(CLIENT_CREDENTIALS)、授权码模式(AUTHORIZATION_CODE)请求时携带的请求参数,后两个类是grat-type为刷新token(REFRESH_TOKEN)和JWT(JWT_BEARER)的请求封装类,而四大授权模式中的隐式授权模式(IMPLICIT)并没有在此定义的原因应该是因为官方并不建议使用这种模式,因为在HTTP重定向中返回访问令牌(而不确认客户端已接收到令牌)存在固有风险 - 第二类:返回类:我们可以看到和上述五个类平级的还有一个
OAuth2AccessTokenResponseClient类,这个类及其子类是封装的不同模式的不同返回封装类,OAuth2AccessTokenResponseClient是一个函数式接口,接收一个AbstractOAuth2AuthorizationGrantRequest的子类的入参,返回OAuth2AccessTokenResponse,其下属子类便是对不同模式的返回值的封装,大致类容是根据不同模式的请求封装requestEntity并发送请求到具体端点,然后封装OAuth2AccessTokenResponse并返回。
7.10 OAuth2UserService 从UserInfo端点获取终端用户属性

OAuth2UserService是一个函数式接口,只包含一个loadUser方法,
- DelegatingOAuth2UserService:内部包含一个
OAuth2UserService集合,每个OAuth2UserService都有机会加载一个OAuth2User,并返回第一个非空的OAuth2User - OidcUserService:内部包含一个
OAuth2UserService,默认是DefaultOAuth2UserService,利用这个OAuth2UserService的loadUser加载并封装信息返回 - DefaultOAuth2UserService:默认利用
OAuth2UserRequestEntityConverter转换RequestEntity并发送请求来加载用户信息并返回
7.11 GrantedAuthoritiesMapper 加载权限的mapper

- SimpleAuthorityMapper:简单的一对一 GrantedAuthoritiesMapper,它允许权限名称的大小写转换和添加字符串前缀(默认为ROLE_)。
- RoleHierarchyAuthoritiesMapper:利用
RoleHierarchy来获取用户权限 - NullAuthoritiesMapper:什么都不做,直接返回原有权限
7.12 UserDetailsChecker 用户信息检查

用来检查用户信息是否有问题,本质都是调用UserDetails类里的方法进行判断。
- DefaultPostAuthenticationChecks:
AbstractUserDetailsAuthenticationProvider类的内部类,负责后置检查用户信息,这个类检查了用户密码是否过期 - DefaultPreAuthenticationChecks:
AbstractUserDetailsAuthenticationProvider类的内部类,负责前置检查用户信息,这个类检查了用户账号是否锁定、账号是否启用、账号是否过期 - AccountStatusUserDetailsChecker:检查了用户账户是否锁定、用户是否启用、用户账号是否过期、用户密码是否过期
8.鉴权
未完待续
本文深入探讨了Spring Security框架的核心组件,包括SecurityContextHolder上下文持有器、ConfigAttribute配置属性、GrantedAuthority权限封装、Authentication认证过程、UserDetailsService用户数据加载以及OAuth2相关类。讲解了各个组件的功能、用途及其实现策略,如线程安全的策略、角色层次结构、用户信息检查等,为理解和使用Spring Security提供了详尽的指南。
3532

被折叠的 条评论
为什么被折叠?



