我是Spring Security的初学者,我想了解过滤器的顺序。基于一个展示如何执行JWT身份验证的Github存储库,我注意到作者使用的SecurityConfiguration。addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
在UsernamePasswordAuthenticationFilter
之前添加JWT过滤器。我不明白的是,当在调试模式下启动项目时,UsernamePasswordAuthenticationFilter
永远不会加载。为什么要将他的过滤器放在UsernamePasswordAuthenticationFilter之前?如果未添加UsernamePasswordAuthenticationFilter会发生什么?我以为过滤器会被添加到链的末尾,但它最终被放置在LogoutFilter之后。
@Configuration
@EnableWebSecurity(debug = true)
@RequiredArgsConstructor
@EnableMethodSecurity
public class SecurityConfiguration {
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authenticationProvider;
private final LogoutHandler logoutHandler;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers(
"/api/v1/auth/**",
"/v2/api-docs",
"/v3/api-docs",
"/v3/api-docs/**",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui/**",
"/webjars/**",
"/swagger-ui.html"
)
.permitAll()
.requestMatchers("/api/v1/management/**").hasAnyRole(ADMIN.name(), MANAGER.name())
.requestMatchers(GET, "/api/v1/management/**").hasAnyAuthority(ADMIN_READ.name(), MANAGER_READ.name())
.requestMatchers(POST, "/api/v1/management/**").hasAnyAuthority(ADMIN_CREATE.name(), MANAGER_CREATE.name())
.requestMatchers(PUT, "/api/v1/management/**").hasAnyAuthority(ADMIN_UPDATE.name(), MANAGER_UPDATE.name())
.requestMatchers(DELETE, "/api/v1/management/**").hasAnyAuthority(ADMIN_DELETE.name(), MANAGER_DELETE.name())
/* .requestMatchers("/api/v1/admin/**").hasRole(ADMIN.name())
.requestMatchers(GET, "/api/v1/admin/**").hasAuthority(ADMIN_READ.name())
.requestMatchers(POST, "/api/v1/admin/**").hasAuthority(ADMIN_CREATE.name())
.requestMatchers(PUT, "/api/v1/admin/**").hasAuthority(ADMIN_UPDATE.name())
.requestMatchers(DELETE, "/api/v1/admin/**").hasAuthority(ADMIN_DELETE.name())*/
.anyRequest()
.authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.logout()
.logoutUrl("/api/v1/auth/logout")
.addLogoutHandler(logoutHandler)
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext())
;
return http.build();
}
}
字符串
如果我没有激活我的过滤器链,我有UsernamePasswordAuthenticationFilter。我想了解Spring如何在自定义配置中管理.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
。
1条答案
按热度按时间u0sqgete1#
为什么要将他的过滤器放在UsernamePasswordAuthenticationFilter之前?
因为一旦你有了jwt令牌,你就不想浪费时间通过其他身份验证过滤器,比如usernameAndPasswordAuthFilter,你应该先点击jwtFilter来保存时间。
如果未添加UsernamePasswordAuthenticationFilter会发生什么?
UsernamePasswordFilter是否在securityFilterChain中并不重要,因为每个已知的过滤器都有一个Order,如(100,200,300,...),一旦您在它之前添加了一个过滤器,您的过滤器就会被分配一个顺序(100-1,200-1,300-1,...),因此,即使添加了UsernamePasswordFilter,它的顺序在安全过滤器链中也是已知的,并且可以用于为您的jwtFilter分配顺序
我原以为过滤器会被添加到链的末尾,但它最终被放置在LogoutFilter之后
这是合理的,如果你检查这里的安全过滤器的顺序,你会发现你的jwtFilter被插入在UsernamePasswordFilter之前。