从整个SecurityFilterChain的角度,一个请求经过Spring Security的流程
从整个SecurityFilterChain的角度,一个请求经过Spring Security的流程
- 每个请求对应一个SecurityFilterChain和一系列的Filter,这些Filter根据预设的顺序排序。在项目启动日志中会打印出filter的顺序,以下是一个例子
2024-12-13 11:53:58.829 [main] INFO org.springframework.security.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@7b4c793b, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@51a69e8f, org.springframework.security.web.context.SecurityContextPersistenceFilter@bc88295, org.springframework.security.web.header.HeaderWriterFilter@e2498a3, org.springframework.security.web.csrf.CsrfFilter@66f5770e, org.springframework.security.web.authentication.logout.LogoutFilter@c4455b4, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@277474fc, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@5ab3f611, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@10280879, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@7e9ed4df, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@453e1bba, org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter@44aa5585, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@6442cf3e, org.springframework.security.web.session.SessionManagementFilter@6a7ab205, org.springframework.security.web.access.ExceptionTranslationFilter@2e1c5d1f, org.springframework.security.web.access.intercept.AuthorizationFilter@6d658aa8]
- 先执行CsrfFilter等排序靠前的filter,这些filter执行完自己的逻辑后会调用filterChain.doFilter方法执行filterChain的下一个filter的doFilter方法
- 进入认证filter逻辑。当http请求是一个认证请求时(由filter.requestMatcher的matches方法判断),这个请求交由相应的filter处理,否则调用filterChain.doFilter方法执行下一个filter的处理逻辑。比如/user/login交由UsernamePasswordAuthenticationFilter处理,/user/login/oauth2/callback交由OAuth2LoginAuthenticationFilter处理。认证filter处理的特点是一般情况下,只要进入了认证filer的处理,无论attemptAuthentication方法是否返回了Authentication对象,都不会调用filterChain.doFilter方法。
- 执行其他filter逻辑
- 最后进入授权filter逻辑,实现类为AuthorizationFilter。会执行AuthorizationManager.check方法返回一个AuthorizationDecision,用来决定是否授权该请求的访问。如果不允许访问,则抛出AccessDeniedException。否则调用chain.doFilter方法执行SecurityFilterChain的收尾工作(AuthorizationFilter通常是最后一个)。
自己的码云spring-security练习项目:code_practice_2024/spring-security,成功接入了GitHub,华为OAuth2,欢迎访问