以下是我在迁移前的工作安全配置:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/auth/**")
.antMatchers("/swagger-ui/**")
.antMatchers("/swagger-ui.html")
.antMatchers("/swagger-resources/**")
.antMatchers("/v2/api-docs/**")
.antMatchers("/v3/api-docs/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedPortalRoleConverter);
http
.csrf().disable()
.cors()
.and()
.exceptionHandling()
.authenticationEntryPoint(new AuthenticationFallbackEntryPoint())
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests(authorize -> authorize.anyRequest().authenticated())
.oauth2ResourceServer()
.jwt().jwtAuthenticationConverter(jwtAuthenticationConverter);
}
以下是我在迁移后的安全链配置:
@Bean
@Order(1)
public SecurityFilterChain ignorePathsSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.antMatchers(
"/auth/**",
"/swagger-ui/**",
"/swagger-ui.html",
"/swagger-resources/**",
"/v3/api-docs/**")
.permitAll());
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http, GrantedPortalRoleConverter grantedPortalRoleConverter) throws Exception {
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedPortalRoleConverter);
http
.csrf().disable()
.cors(Customizer.withDefaults())
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(new AuthenticationFallbackEntryPoint()))
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
.oauth2ResourceServer(configurer -> configurer.jwt().jwtAuthenticationConverter(jwtAuthenticationConverter));
return http.build();
}
对于原始conf,当我调用一个随机的不存在路径时:
@Test
void should_not_authenticate_or_return_not_found() throws Exception {
logger.info("should_not_authenticate_or_return_not_found");
mvc.perform(get("/toto/tata"))
.andExpect(status().isUnauthorized());
}
我得到:
15:44:00.230 [main] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Failed to authorize filter invocation [GET /toto/tata] with attributes [authenticated]
有了新的配置文件,我只得到HTTP 404,请问我在这里错过了什么?我看不到任何区别,调试日志也没有显示太多。
下面是使用非工作配置时日志丢失的第一行:
16:24:58.651 [main] DEBUG o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource - Adding web access control expression [authenticated] for any request
但在两个日志中,我可以看到(新配置有两行,因为有两个安全链):
o.s.s.web.DefaultSecurityFilterChain - Will secure any request with (...)
1条答案
按热度按时间c9x0cxw01#
说明
当您有多个
SecurityFilterChain
时,您必须指定一个请求匹配器,否则所有请求将由第一个SecurityFilterChain
(用@Order(1)
注解)处理,并且永远不会到达第二个SecurityFilterChain
(用@Order(2)
注解)。在上面共享的代码中,这意味着在
ignorePathsSecurityFilterChain
中配置.requestMatchers()
:这意味着只有与
/auth/**
、/swagger-ui/**
等匹配的请求将由ignorePathsSecurityFilterChain
处理,而其余请求将移动到defaultSecurityFilterChain
。要了解
requestMatchers
和authorizeHttpRequests
之间的区别,您可以查看此StackOverflow问题。解决方案
一个更好的选择是将
SecurityFilterChain
组合成一个单独的。我看不出在这种情况下有什么理由要将它们分开。生成的配置为:
替代
或者,您可以使用
WebSecurityCustomizer
来忽略某些端点:然后,您将使用
defaultSecurityFilterChain
作为唯一的SecurityFilterChain
。