Spring Security原理

FilterChain

image.png

  • SecurityContextPersistenceFilter:请求进入,查看session有没有认证信息。放入Context中。
  • UsernamePasswordAuthenticationFilter:验证密码
  • ExceptionTranslationFilter:处理错误
  • FilterSecurityInterceptor:总拦截器,如果错误,会抛异常由ExceptionTranslationFilter处理。

AuthenticationFilter原理

image.png
AuthenticationFilter提取出token,将token交给AuthenticationManager

this.getAuthenticationManager().authenticate(token);

AuthenticationManager会注册多种AuthenticationProvider,不同Provider对应不同的token。

ProviderManager#authenticate result = provider.authenticate(authentication);

AbstractUserDetailsAuthenticationProvider#authenti cate中:
image.png
retrieveUser()中调用UserDetailsService获取UserDetails
image.png
验证用户:
image.png
使用passwordEncoder来校验密码
image.png

返回SuccessAuthentication。
返回到AbstractAuthenticationProcessingFilter#doFilter
image.png

image.png
successful内部处理rememberMe。

  • 生成RememberMe的token,写入cookie

image.png

配置组件

WebSecurity和HttpSecurity

  1. @Override
  2. protected void configure(HttpSecurity http) throws Exception {
  3. http
  4. .csrf(csrf -> csrf.ignoringAntMatchers("/api/**", "/admin/**", "/authorize/**"))
  5. // .apply(clientErrorLogging()).and()
  6. .authorizeRequests(authorizeRequests -> authorizeRequests
  7. .antMatchers("/authorize/**").permitAll()
  8. .antMatchers("/admin/**").hasRole("ADMIN")
  9. .antMatchers("/api/**").hasRole("USER")
  10. .anyRequest().authenticated())
  11. .addFilterAt(restAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
  12. .formLogin(login -> login
  13. .loginPage("/login")
  14. // .failureUrl("/login?error")
  15. .failureHandler(jsonLoginFailureHandler())
  16. .successHandler(new UaaSuccessHandler())
  17. // .successHandler(jsonLoginSuccessHandler())
  18. // .defaultSuccessUrl("/")
  19. .permitAll())
  20. .logout(logout -> logout
  21. .logoutUrl("/perform_logout")
  22. // .logoutSuccessUrl("/login")
  23. .logoutSuccessHandler(jsonLogoutSuccessHandler())
  24. )
  25. .rememberMe(rememberMe -> rememberMe
  26. .key("someSecret")
  27. .tokenValiditySeconds(86400))
  28. .httpBasic(Customizer.withDefaults()); // 显示浏览器对话框,需要禁用 CSRF ,或添加路径到忽略列表
  29. }
  30. @Override
  31. public void configure(WebSecurity web) throws Exception {
  32. web
  33. .ignoring()
  34. .antMatchers("/public/**")
  35. .requestMatchers(PathRequest.toStaticResources().atCommonLocations());
  36. }


image.png
HttpSecurity是用来构建包含了一系列过滤器链的过滤器SecurityFilterChain
WebSecurity 用来创建核心过滤器FilterChainProxy实例

自定义filter

image.png
替换UsernamePasswordAuthenticationFilter

  1. http.addFilterAt(restAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)

UserDetailsService:通过用户名加载数据库中的用户数据

image.png

tokenStore & tokenEnhancer

tokenEnhancer对token做进一步处理
image.png
image.png
image.png

其他

csrf

image.png