Spring Security原理
FilterChain
- SecurityContextPersistenceFilter:请求进入,查看session有没有认证信息。放入Context中。
- UsernamePasswordAuthenticationFilter:验证密码
- ExceptionTranslationFilter:处理错误
- FilterSecurityInterceptor:总拦截器,如果错误,会抛异常由ExceptionTranslationFilter处理。
AuthenticationFilter原理
AuthenticationFilter提取出token,将token交给AuthenticationManager
this.getAuthenticationManager().authenticate(token);
AuthenticationManager会注册多种AuthenticationProvider,不同Provider对应不同的token。
ProviderManager#authenticate result = provider.authenticate(authentication);
AbstractUserDetailsAuthenticationProvider#authenti cate中:
retrieveUser()中调用UserDetailsService获取UserDetails
验证用户:
使用passwordEncoder来校验密码
返回SuccessAuthentication。
返回到AbstractAuthenticationProcessingFilter#doFilter
successful内部处理rememberMe。
- 生成RememberMe的token,写入cookie
配置组件
WebSecurity和HttpSecurity
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.ignoringAntMatchers("/api/**", "/admin/**", "/authorize/**"))
// .apply(clientErrorLogging()).and()
.authorizeRequests(authorizeRequests -> authorizeRequests
.antMatchers("/authorize/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/api/**").hasRole("USER")
.anyRequest().authenticated())
.addFilterAt(restAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.formLogin(login -> login
.loginPage("/login")
// .failureUrl("/login?error")
.failureHandler(jsonLoginFailureHandler())
.successHandler(new UaaSuccessHandler())
// .successHandler(jsonLoginSuccessHandler())
// .defaultSuccessUrl("/")
.permitAll())
.logout(logout -> logout
.logoutUrl("/perform_logout")
// .logoutSuccessUrl("/login")
.logoutSuccessHandler(jsonLogoutSuccessHandler())
)
.rememberMe(rememberMe -> rememberMe
.key("someSecret")
.tokenValiditySeconds(86400))
.httpBasic(Customizer.withDefaults()); // 显示浏览器对话框,需要禁用 CSRF ,或添加路径到忽略列表
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/public/**")
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
HttpSecurity是用来构建包含了一系列过滤器链的过滤器SecurityFilterChain
WebSecurity 用来创建核心过滤器FilterChainProxy实例
自定义filter
替换UsernamePasswordAuthenticationFilter
http.addFilterAt(restAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)