前置准备
使用SpringSecurity框架之前,需要自定义配置类SecurityConfig,该配置类继承自WebSecurityConfigurerAdapter
在 Spring Security 中,很多对象都是手动 new 出来的,这些 new 出来的对象和容器没有任何关系。在接下来的登录流程中需要使用到AuthenticationManager
对象,所以需要重写authenticationManagerBean()
方法,添加@Bean注解使其被容器管理
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
另外,需要重写三个configure方法
void configure(AuthenticationManagerBuilder auth) 为身份认证接口,用来配置认证管理器AuthenticationManager。
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
void configure(WebSecurity web) 用来配置 WebSecurity 。而 WebSecurity 是基于 Servlet Filter 用来配置 springSecurityFilterChain 。而 springSecurityFilterChain 又被委托给了 Spring Security 核心过滤器 Bean DelegatingFilterProxy 。 相关逻辑可以在 WebSecurityConfiguration 中找到。我们一般不会过多来自定义 WebSecurity ,使用较多的是其ignoring() 方法用来忽略 Spring Security 对静态资源的控制
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
/**
1. anyRequest | 匹配所有请求路径
2. access | SpringEl表达式结果为true时可以访问
3. anonymous | 匿名可以访问
4. denyAll | 用户不能访问
5. fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)
6. hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
7. hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
8. hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
9. hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
10. hasRole | 如果有参数,参数表示角色,则其角色可以访问
11. permitAll | 用户可以任意访问
12. rememberMe | 允许通过remember-me登录的用户访问
13. authenticated | 用户登录后可访问
*/
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// CSRF禁用,因为不使用session
.csrf().disable()
// 认证失败处理类,指定异常处理实现类
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 基于token,所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
// 对于登录login 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/captchaImage").anonymous()
.antMatchers(
HttpMethod.GET,
//添加前端所有静态资源路径
"/*.ttf",
...
).permitAll()
//添加公共api路径
.antMatchers("/common/downloadByMinio**").permitAll()
...
// 除上面外的所有请求全部需要鉴权认证