Spring Security 整体架构
整体架构
在的架构设计中,认证 和 授权
是分开的,无论使用什么样的认证方式。都不会影响授权,这是两个独立的存在,这种独立带来的好处之一,就是可以非常方便地整合一些外部的解决方案。
认证
AuthenticationManger
在Spring Security中认证是由AuthenticationManager`接口来负责的
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
-
返回Authentication 表示认证成功
-
返回AuthenticationException异常,表示认证失败。
AuthenticationManager主要实现类为ProviderManager,在ProviderManager中管理了众多AuthenticationProvider实例。在一次完整的认证流程中,Spring Security允许存在多个AuthenticationProvider,用来实现多种认证方式,这些AuthenticationProvider都是由ProviderManager 进行统一管理的。
Authentication
认证以及认证成功的信息主要是由 Authentication 的实现类进行保存的,其接口定义为:
-
getAuthorities获取用户权限信息
-
getCredentials获取用户凭证信息,一般指密码
-
getDetails获取用户详细信息
-
getPrincipal获取用户身份信息,用户名、用户对象等
-
isAuthenticated用户是否认证成功
SecurityContextHolder
SecurityContextHolder用来获取登录之后用户信息。Spring Security 会将登录用户数据保存在Session中。但是,为了使用方便,Spring Security在此基础上还做了一些改进,其中最主要的一个变化就是线程绑定。当用户登录成功后,Spring Security会将登录成功的用户信息保存到SecurityContextHolder 中。SecurityContextHolder 中的数据保存默认是通过ThreadLocal来实现的,使用 ThreadLocal创建的变量只能被当前线程访问,不能被其他线程访问和修改,也就是用户数据和请求线程绑定在一起。当登录请求处理完毕后,SpringSecurity会将SecurityContextHolder 中的数据拿出来保存到Session中,同时将 SecurityContexHolder 中的数据清空。以后每当有请求到来时,Spring Security 就会先从 Session 中取出用户登录数据,保存到SecurityContextHolder中,方便在该请求的后续处理过程中使用,同时在请求结束时将SecurityContextHolder中的数据拿出来保存到 Session 中,然后将 SecuritySecurityContextHolder中的数据清空。这一策略非常方便用户在 Controller、Service 层以及任何代码中获取当前登录用户数据。
授权
AccessDecisionManager
AccessDecisionManager(访问决策管理器)1用来决定此次访问是否被允许。
AccessDecisionVoter
AccessDecisionVoter(访问决定投票器),投票器会检查用户是否具备应有的角色进而投出赞成、反对或者弃权票。
AccessDecisionVoter和AccessDecisionManager都有众多的实现类,在AccessDecisionManager中会换个遍历AccessDecisionVoter,进而决定是否允许用户访问,因而AveasDecisionVoter和AccessDecisionManager两者的关系类似于AuthenticationProvider和 ProviderManager 的关系。
ConfigAttribute
ConfigAttribute,用来保存授权时的角色信息
在Spring Security 中,用户请求一个资源(通常是一个接口或者一个Java方法)需要的角色会被封装成一个ConfigAttribute对象,在ConfigAttribute中只有一个getAttribute方法,该方法返回一个String 字符串,就是角色的名称。一般来说,角色名称都带有一个ROLE_前缀,投票器AccessDecisionVoter所做的事情,其实就是比较用户所具各的角色和请求某个资源所需的ConfigAtuibute之间的关系。