Spring 引导 HTTP 安全配置匿名过滤器和不同路径上的自定义过滤器
Spring Boot HTTP security configuration anonymous filter and a custom filter on a different path
我在尝试使用 WebSecurityConfigurerAdapter 配置 HTTP 安全性时遇到了一个奇怪的问题。这是完整的配置 class 目前为止我试过:
@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
@ConditionalOnProperty(name = "module.client.security.enabled")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${management.endpoints.web.base-path}")
private String managementEndpoint;
@Autowired
private List<ModuleProperties> moduleProperties;
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers(this.managementEndpoint + "/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
http.formLogin().disable();
// FIXME also doesn't work because of the later http.requestMatchers().antMatchers() calls
http.authorizeRequests()
.antMatchers("/**").anonymous();
http.requestMatchers()
.antMatchers("/app/**")
.and()
.addFilterBefore(new ClientResolveFilter(), FilterSecurityInterceptor.class);
}
我想做的实际上是为所有端点启用匿名身份验证 — 以防止在 SecurityContextHolder 上操作时出现 NullPointerException — 另外, enabling/adding 自定义过滤器仅针对一个子集或不同的端点路径,在这种情况下为 /app/**
。
我预计上面的代码会起作用,但实际发生的是 AnonymousAuthenticationFilter 对所有人禁用,并且两个过滤器仅适用于路径 /app/**
。
如果我删除了 http.requestMatchers().antMatchers("/app/**")
部分,那么 AnonymousAuthenticationFilter 将照常适用于所有路径。我怀疑第二个 .antMatchers("/app/**")
调用有点取代前一个或隐式替换它,这对我来说没有意义,但我可能是错的。
我尝试深入研究源代码,但仍然感到困惑,无法找到一个干净的解决方案来使其按我的预期工作。任何想法和帮助将不胜感激。
干杯!
编辑:我正在使用 Spring Boot 2.5.2,Spring 安全版本是 5.5.1
addFilterBefore
(和其他 addFilter*)方法会将过滤器添加到适用于所有请求的过滤器链中。如果您希望过滤器仅适用于某些请求,则必须检查过滤器内部(例如,使用 HttpServletRequest.getgetRequestURI()
检查 url)。
在@Dickson 的建议下,我找到了一个由 spring boot 提供的名为 FilterRegistrationBean
的特殊 bean。
因此,我将其配置为一个 bean,它仅将特定的 servlet 过滤器应用于已配置的路径:
@Bean
public FilterRegistrationBean<ClientResolveFilter> clientResolveFilter(){
final FilterRegistrationBean<ClientResolveFilter> frb = new FilterRegistrationBean<>();
frb.setFilter(new ClientResolveFilter());
frb.addUrlPatterns("/app/*");
return frb;
}
这个解决方案非常适合我的要求。
注意路径字符串现在不是蚂蚁匹配器——必须写成单/app/*
而不是双/app/**
——它实际上是我们像过去一样手动配置 web.xml 文件时的模式:)
我在尝试使用 WebSecurityConfigurerAdapter 配置 HTTP 安全性时遇到了一个奇怪的问题。这是完整的配置 class 目前为止我试过:
@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
@ConditionalOnProperty(name = "module.client.security.enabled")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${management.endpoints.web.base-path}")
private String managementEndpoint;
@Autowired
private List<ModuleProperties> moduleProperties;
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers(this.managementEndpoint + "/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable();
http.formLogin().disable();
// FIXME also doesn't work because of the later http.requestMatchers().antMatchers() calls
http.authorizeRequests()
.antMatchers("/**").anonymous();
http.requestMatchers()
.antMatchers("/app/**")
.and()
.addFilterBefore(new ClientResolveFilter(), FilterSecurityInterceptor.class);
}
我想做的实际上是为所有端点启用匿名身份验证 — 以防止在 SecurityContextHolder 上操作时出现 NullPointerException — 另外, enabling/adding 自定义过滤器仅针对一个子集或不同的端点路径,在这种情况下为 /app/**
。
我预计上面的代码会起作用,但实际发生的是 AnonymousAuthenticationFilter 对所有人禁用,并且两个过滤器仅适用于路径 /app/**
。
如果我删除了 http.requestMatchers().antMatchers("/app/**")
部分,那么 AnonymousAuthenticationFilter 将照常适用于所有路径。我怀疑第二个 .antMatchers("/app/**")
调用有点取代前一个或隐式替换它,这对我来说没有意义,但我可能是错的。
我尝试深入研究源代码,但仍然感到困惑,无法找到一个干净的解决方案来使其按我的预期工作。任何想法和帮助将不胜感激。
干杯!
编辑:我正在使用 Spring Boot 2.5.2,Spring 安全版本是 5.5.1
addFilterBefore
(和其他 addFilter*)方法会将过滤器添加到适用于所有请求的过滤器链中。如果您希望过滤器仅适用于某些请求,则必须检查过滤器内部(例如,使用 HttpServletRequest.getgetRequestURI()
检查 url)。
在@Dickson 的建议下,我找到了一个由 spring boot 提供的名为 FilterRegistrationBean
的特殊 bean。
因此,我将其配置为一个 bean,它仅将特定的 servlet 过滤器应用于已配置的路径:
@Bean
public FilterRegistrationBean<ClientResolveFilter> clientResolveFilter(){
final FilterRegistrationBean<ClientResolveFilter> frb = new FilterRegistrationBean<>();
frb.setFilter(new ClientResolveFilter());
frb.addUrlPatterns("/app/*");
return frb;
}
这个解决方案非常适合我的要求。
注意路径字符串现在不是蚂蚁匹配器——必须写成单/app/*
而不是双/app/**
——它实际上是我们像过去一样手动配置 web.xml 文件时的模式:)