Security
Security基础知识
认证
void configure(AuthenticationManagerBuilder auth)
- 基于内存用户认证(inMemoryAuthentication)
- 基于数据库用户认证(jdbcAuthentication)
- 基于LDAP服务器方式用户认证(ldapAuthentication)
- 自定义用户认证(UserDetailsService)(适用于响应式)
自定义用户认证详细说明:
数据库映射实体类需要实现UserDetails接口,重写getAuthorities()方法返回用户权限集合,各种is方法返回Boolean。创建CRUD的Repository(定义findByUsername())。
服务层需要实现UserDetailsService接口
public interface UserDetailsService {
//对应创建CRUD的Repository的定义findByUsername()
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
PasswordEncode 接口实现:
- BCryptPasswordEncoder: bcrypt强哈希加密
- NoOpPasswordEncoder: 不进行转码
- Pbkdf2PasswordEncoder: PBKDF2加密
- SCryptPasswordEncoder: scrypt哈希加密
- StandardPasswordEncoder: SHA-256哈希加密
- 自定义实现passwordEncode接口
public interface PasswordEncode {
String encode(CharSequence rawPassword);
boolean matches(CharSequence rawPassword,String encodedPassword);
}
passwordEncode接口的实现,不是解码数据库密码,而是对输入进行加密,然后比对(matches()方法)加密后的内容。
保护
void configure(HttpSecurity http) throws Exception
几种功能:
- 对特定请求进行条件验证(接口权限配置)
- 配置自定义登录页面
- 支持用户退出应用
- 预防跨站请求伪造
注意: 在实际代码规则声明中,前面的规则优先级高于后面的优先级(前面的规则先被匹配)
利用SpEL表达式和access()能实现自定义权限。
csrf关闭方法: .and().csrf().disable()
审核
确定用户:
- 注入Principal对象,从UserRepository中查找用户
- 注入Authentication对象,调用getPrincipal()强制转为User
- SecurityContextHolder,获取上下文,再获取Authentication对象
- 接收时用@AuthenticationPrincipal注解标注方法user参数。
响应式
ReactiveSecurityContextHolder 依赖于 Reactor Context API
ReactiveSecurityContextHolder.getContext().block() 会获取一个空的上下文,因为上下文解析的策略是惰性的。
需要使用spring5为security提供的新新模块ReactorContextWebFilter,ReactorContextWebFilter#subcriberContext通过ServerSecurityContextRepository来执行解析
public interface ServerSecurityContextRepository {
Mono<Void> save(ServerWebExchange var1, SecurityContext var2);
Mono<SecurityContext> load(ServerWebExchange var1);
}