springSecurity简介
Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案,是一种基于Spring AOP和Servlet规范中的Filter实现的安全框架,其本质是一个过滤器链
名词解释
**主体(principal)**使用系统的用户或设备或从其他系统远程登录的用户等等,谁在使用该系统
**认证(authentication)**权限管理系统确认一个主体的身份,允许主体进入系统,“主体”证明自己是谁。
**授权(authorization)**将操作系统的“权力”授予“主体”,这样主体就具备了操作系统中特定功能的能力,授权就是给用户分配权限
1 | <dependency> |
核心类
SecurityContextHolder 用于存储安全上下文的信息,当前用户、是否被认证、权限都存储在其中
提供了三种存储策略,当然也可以自定义储存策略,设置strategyName来进行反射获取
- MODE_THREADLOCAL 使用ThreadLocalSecurityContextHolderStrategy
- MODE_INHERITABLETHREADLOCAL 使用InheritableThreadLocalSecurityContextHolderStrategy
- MODE_GLOBAL 使用GlobalSecurityContextHolderStrategy
Authentication 继承自Principal,可以通过该接口来获取到用户的权限、密码以及身份信息和认证信息
- getAuthorities 获取权限
- getCredentials 获取密码,用户提交的密码
- getDetails 获取详情
- getPrincipal 获取认证信息,返回的是UserDetails的实现类
AuthenticationManager 认证相关的核心接口,定义了认证方法authenticate
1
2Authentication authenticate(Authentication authentication)
throws AuthenticationException;ProviderManager 认证管理,实现了AuthenticationManager,并在authenticate方法中将真正的认证逻辑委托给了AuthenticationProvider对象
DaoAuthenticationProvider 该类是AuthenticationProvider最常用的实现类,用来获取用户提交的用户名和密码对比正确性,实现了其父类的两个抽象方法
1
2
3
4
5
6
7// 用于身份认证
protected abstract void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication)
// 用于从数据库获取用户信息, 这里会调用userDetailsService.loadUserByUsername方法来进行获取
protected abstract UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException;UserDetails 用户信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61public interface UserDetails extends Serializable {
// ~ Methods
// ========================================================================================================
/**
* Returns the authorities granted to the user. Cannot return <code>null</code>.
*
* @return the authorities, sorted by natural key (never <code>null</code>)
*/
Collection<? extends GrantedAuthority> getAuthorities();
/**
* Returns the password used to authenticate the user.
*
* @return the password
*/
// 正确的密码
String getPassword();
/**
* Returns the username used to authenticate the user. Cannot return <code>null</code>
* .
*
* @return the username (never <code>null</code>)
*/
String getUsername();
/**
* Indicates whether the user's account has expired. An expired account cannot be
* authenticated.
*
* @return <code>true</code> if the user's account is valid (ie non-expired),
* <code>false</code> if no longer valid (ie expired)
*/
boolean isAccountNonExpired();
/**
* Indicates whether the user is locked or unlocked. A locked user cannot be
* authenticated.
*
* @return <code>true</code> if the user is not locked, <code>false</code> otherwise
*/
boolean isAccountNonLocked();
/**
* Indicates whether the user's credentials (password) has expired. Expired
* credentials prevent authentication.
*
* @return <code>true</code> if the user's credentials are valid (ie non-expired),
* <code>false</code> if no longer valid (ie expired)
*/
boolean isCredentialsNonExpired();
/**
* Indicates whether the user is enabled or disabled. A disabled user cannot be
* authenticated.
*
* @return <code>true</code> if the user is enabled, <code>false</code> otherwise
*/
boolean isEnabled();
}UserDetailsService 负责获取正确的用户信息,提供了几个实现类,也可以实现UserDetailsService接口来进行自定义
1
2
3
4public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
进行认证
UsernamePasswordAuthenticationFilter
对/login 的 POST 请求做拦截,校验表单中用户名,密码
1 | public Authentication attemptAuthentication(HttpServletRequest request, |
1 | # 配置用户名,密码 |
其中的用户名密码都是spring security生成或者配置的,但是在实际使用中用户名和密码都是从数据库去进行读取的,所以这段逻辑需要进行自定义,如果需要自定义逻辑时,需要实现 UserDetailsService 接口
1 | public interface UserDetailsService { |