我正在尝试在春季启用网络安全。我实际上有两个端点(一个 GET 和一个 POST(,我想为每个请求使用不同的GenericFilterBean
。
我已经尝试了下面的代码,但我无法获得所需的行为。对于每个请求(GET 和 POST(,都会调用两个过滤器(GetUserIdByToken 和 AuthUserIdTransactionId(。你们能给我一个解决方案吗?每个请求只有一个过滤器。提前谢谢。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.requestMatchers()
.antMatchers(HttpMethod.GET, "/me/accounts/{accountId}/transactions")
.and()
.addFilterBefore(new GetUserIdByToken(), BasicAuthenticationFilter.class)
.requestMatchers()
.antMatchers(HttpMethod.POST, "/me/accounts/{accountId/transactions/{transactionId}")
.and()
.addFilterBefore(new AuthUserIdTransactionId(), BasicAuthenticationFilter.class);
}
}
每当配置HttpSecurity
时,您都在配置最终将出现在FilterChain
中的内容。这意味着,如果调用筛选器链,将调用添加到HttpSecurity
的每个筛选器。
方法 1
如果要有选择地"关闭"FilterChain
中的某些过滤器,则可以将它们配置为这样做:
public class GetUserIdByToken extends GenericFilterBean {
private AntPathRequestMatcher requestMatcher;
public GetUserIdByToken(String path, HttpMethod method) {
this.requestMatcher = new AntPathRequestMatcher(path, method);
}
// ...
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
if(!this.requestMatcher.matches(req) {
chain.doFilter(req,resp);
return;
}
// filter logic goes here...
}
}
你可以对AuthUserIdTransactionId
做同样的事情。然后,只需将适当的路径和 http 方法传递给每个构造函数,并将两个过滤器添加到 HttpSecurity
中。
方法 2
另一方面,如果您想要一个 完全独立的FilterChain
,您必须配置两个WebSecurityConfigurerAdapter
。这篇博文解释了如何很好地做到这一点。或者您可以查看官方文档。