spring-boot - 如何进一步停止处理请求?
问题描述
如果请求中不存在某个标头,我需要阻止所有请求处理。因此,我有以下 SecurityConfig 代码,我在其中配置了一个在其他所有操作之前执行的过滤器:
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.addFilterBefore(
new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
if(testmode) {
String testModeHeader = request.getHeader("TestMode");
System.out.println("In testmode :"+request.getRequestURI()+" "+testModeHeader);
if(!testmodeHeaderValue.equals(testModeHeader)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
response.flushBuffer();
return;
}
}
chain.doFilter(request, response);
}
}
, SecurityContextPersistenceFilter.class);
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/oauth/**", "/oauth2/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(oauthUserService)
.and()
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
...code not shown...
}
})
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
尽管使用flushBuffer发送错误代码并提交响应,但似乎spring boot仍在将用户重定向到登录页面,如下输出所示:
In testmode :/token null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
In testmode :/oauth2/authorization/google null
我需要做些什么来提交响应而不通过任何其他过滤器?
而且我不确定当我只向 /token 发出一个请求时,它会收到这么多对 /oauth2/authorization/google 的请求是什么?
解决方案
您看到的行为是尝试呈现默认错误视图 ( /error
) 以及Spring Security 采用的默认安全原则(参见示例 86)。
由于您在响应中返回 401 状态代码,因此/error
正在内部调用视图,这导致第二次通过过滤器链。由于您的过滤器 extends OncePerRequestFilter
,它不会被第二次调用,使它看起来被跳过了。
随后,Spring Security 过滤器链的其余部分启动,检测到未经授权的/error
视图访问,并重定向到/login
,或者在您的情况下,因为您使用的是 oauth2 依赖项,所以/oauth2/authorization/google
页面。然后循环无限地继续。
在这种情况下,一个简单的解决方法是通过.mvcMatchers("/error").permitAll()
或类似方式公开错误页面。值得考虑的是这是否有意义,或者这样做是否会暴露敏感信息。您可能希望使用另一种技术来处理某些错误,例如 Spring Boot 中的ErrorViewResolver
接口。
推荐阅读
- sql-server - 在 SSAS 中执行查询时出现“多维数据集不存在”
- c# - 使用 CodeDOM 制作动态方法 Country and Population
- c - 编译为 c 时进行垃圾收集的算法
- python - 模型在测试集上表现良好,但在训练和验证集上表现不佳
- c - 如何使用 GDI 和纯 C 编写快递文本?
- java - 处理 BLE 信标的线程:只有一个有效……为什么?
- javascript - 在 express 中使用 async/await
- python - 如何使用opencv识别特定区域的颜色并用它控制覆盆子的输出?
- java - 为什么 VS Code 对我的字段是私有的有问题?
- https - 在实际下载之前,如何可靠地获取通过 http(s) 下载的文件的摘要/哈希/指纹?