SpringSecurity的核心功能:
1.认证:即身份认证(你是谁?)
2.授权:即访问控制(你可以做什么)
SpringSecurity整体架构:
1.认证:
在SpringSecurity种,用户的认证信息主要是由Authentication的实现类来保存的,Authentication的接口定义为
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated);
}
这里接口定义的方法有:
- getAuthorities 方法:用来获取用户的权限。
- getCredentials 方法:用来获取用户凭证,一般来说就是密码。
- getDetails 方法:用来获取用户携带的详细信息,可能是当前请求乊类等。
- getPrincipal 方法:用来获取当前用户,例如是一个用户名或者一个用户对象。
- isAuthenticated:当前用户是否认证成功。
当用户使用用户名/密码登录或者使用Remember-me登录时,都会对应一个Authentication实例
当把认证信息保存了之后,当用户来登录时,需要进行认证工作,这个工作交给了由 AuthenticationManager 接口来负责,下面是该接口的定义
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication)
throws AuthenticationException;
}
AuthenticationManager只有一 个 authenticate 方法可以用来做认证,该方法有三个返回值:
- 返回Authentication,表示认证成功
- 返回AuthenticationException异常,表示用户输入无效的凭证
- 返回null,表示不能确定
AuthenticationManager最主要的实现类是ProviderManager,ProviderManager,管理了众多的AuthenticationProvider实例,而AuthenticationProvider又处理了众多的Authentication的实现类,这些不同的实现类,需要不同的AuthenticationProvider来进行处理,所以在AuthenticationProvider中提供了一个supports方法,来判断是否支持给定的Authentication类型。
2. 授权:
当完成认证之后,接下来就是授权了,在SpringSecurity的授权体系中有两个关键接口:
- AccessDecisionManager
- AccessDecisionVoter
AccessDecisionVoter是一个投票器,投票器会检查用户是否具备应有的角色,进而投出赞成,反对或者弃权,AccessDecisionManager 则是一个决策器,来决定此次访问是否被允许。
在AccessDecisionManager 中会挨个遍历AccessDecisionVoter,进而决定是否允许用户访问。
在SpringSecurity中,用户请求的资源(通常是一个网络接口或者一个java方法)所需要的角色都被封装成一个ConfigAttribute对象,在ConfigAttribute中只有一个getAttribute方法,这个方法返回一个字符串,就是角色的名称,一个来说,角色名称都带有一个ROLE_前缀,投票器AccessDecisionVoter所做的事情,其实就是比较用户所具备的角色和请求某个资源所需的ConfigAttribute之间的关系
3.web安全:
SpringSecurity的基本原理:SpringSecurity的认证,授权等功能都是基于过滤器来实现的。在SpringSecurity中会配置很多的过滤器,这些过滤器按照既定的优先级排列,最终形成一个过滤器链,开发者还可以自定义过滤器,并通过@Order注解去调整自定义过滤器在过滤器链中的位置。
需要注意的是,SpringSecurity默认加载的过滤器,并不是直接放在Web项目的原生过滤器链中,而是通过一个FilterChainProxy来统一管理。SpringSecurity中的过滤器链通过FilterChainProxy嵌入到Web项目的原生过滤器中,如图1-1所示。
在SpringSecurity中,这样的过滤器链不仅仅只有一个,可能有很多个,当存在多个过滤器链时,多个过滤器链之间需要指定优先级,当请求到达后,会通过FilterChainProxy进行分发,先和哪个过滤器链匹配上,就用哪个过滤器进行处理,当系统中存在不同的认证体系时,那么使用多个过滤器连接就非常有效