导读
Spring Security是一个提供身份验证、授权和针对常见攻击的保护的框架。它对命令式和反应式应用程序都提供了一流的支持,是保护基于spring的应用程序的事实标准。
原理
流程图
整体流程:
委托给security后的验证流程:
流程分析
典型HTTP处理程序方式,由一系列的fiter调用链组成,无异常情况下请求最终由serverlet去处理:
Filter 过滤器
DelegatingFilterProxy
允许在Servlet容器的生命周期和Spring的生命周期之间进行桥接ApplicationContext
。Servlet容器允许Filter
使用其自己的标准注册,但是它不知道Spring定义的Bean。 DelegatingFilterProxy
可以通过标准Servlet容器机制进行注册,但是将所有工作委托给实现的Spring Bean Filter
。
FilterChainProxy
Spring Security的Filtert支持包含在中FilterChainProxy
。 FilterChainProxy
是Filter
Spring Security提供的一种特殊功能,它允许Filter
通过委派许多实例SecurityFilterChain
。由于FilterChainProxy
是Bean,因此通常将其包装在DelegatingFilterProxy中。
SecurityFilterChain
由FilterChainProxy用于确定Filter
应对此请求调用哪些Spring Security 。
FilterChainProxy维护了多组SecurityChain,每次请求FilterChainProxy会找到匹配的一组,包装成VirtualFilterChain,由VirtualFilterChain进行调用:
目前的所有的Filter列表
ChannelProcessingFilter
ConcurrentSessionFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
CsrfFilter
LogoutFilter
OAuth2AuthorizationRequestRedirectFilter
Saml2WebSsoAuthenticationRequestFilter
X509AuthenticationFilter
AbstractPreAuthenticatedProcessingFilter
CasAuthenticationFilter
OAuth2LoginAuthenticationFilter
Saml2WebSsoAuthenticationFilter
UsernamePasswordAuthenticationFilter
ConcurrentSessionFilter
OpenIDAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
DigestAuthenticationFilter
BearerTokenAuthenticationFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
JaasApiIntegrationFilter
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
OAuth2AuthorizationCodeGrantFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
SwitchUserFilter
Servlet
DispatcheServlet
Spring Mvc的统一入口,它实现了标准的Sevlet Api,它是spring 的基础Servlet。
Security上下文
上下文是有SecurityContextPersistenceFilter放入的,HttpSessionSecurityContextRepository是Session仓库
SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
SecurityContextHolder.setContext(contextBeforeChainExecution);
SecurityContextHolder 包含了SecurityContext,一个hold代表着当前的一个验证用户,获取用户的方式有2种:
1、注解方式
@GetMapping("/")
public String index(@AuthenticationPrincipal User user) {
System.out.println(user);
}
2、调用SecurityContextHolder 方法获取
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
// 用户名/账户
String username = authentication.getName();
// 当前用户,一般是UserDetail的一个实现
Object principal = authentication.getPrincipal();
// 密码信息,验证成功后会清除
Object credentials = authentication.getCredentials();
// 角色权限
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
Security Filter 组成
Security调用流程Filter -> ProvidderManager -> UserDetailsService -> PasswordEncoder
AuthenticationManager
ProviderManager是最常用的实现,它可以由WebSecurityConfigurerAdapter的configure(AuthenticationManagerBuilder auth)构建出来。
ProviderManager
它维护了一组Provicider,每个Provicider可以为自己支持的类型进行表决验证成功或者失败,如果没有找到对应的类型会直接抛出异常,同时它有个parent属性,支持继承,无法验证时会使用parent来完成验证。
UserDetailsService
加载用户使用,加载方式支持多种,比如jdbc,redis,内存等等,用户可以自行扩展。
PasswordEncoder
对请求数据进行编解码操作,security默认提供了多种编码器,也可自行实现。
默认提供了多种编码器,比如:BCryptPasswordEncoder、Pbkdf2PasswordEncoder、SCryptPasswordEncoder、StandardPasswordEncoder等,也允许用户实现自己的编解码器。
DelegatingPasswordEncoder为一个特殊的编码器,它支持一组编码器,通过头匹配模式,进行密码解码和重新编码。在编码格式改变时非常有用。
转载:https://blog.csdn.net/cx105200/article/details/106759400