如何进一步停止处理请求?
How to stop processing request any further?
如果请求中不存在某个 header,我需要阻止所有请求处理。因此,我有以下 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 引导仍将用户重定向到登录页面,如下输出所示:
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 安全所采用的 secure by default principle(参见示例 86)相结合。
由于您在响应中返回 401 状态代码,/error
视图在内部被调用,这导致第二次通过过滤器链。由于您的过滤器扩展了 OncePerRequestFilter
,因此不会在第二次调用它,使其看起来像是被跳过了。
随后,Spring 安全过滤器链的其余部分启动,检测到对 /error
视图的未授权访问,并重定向到 /login
,或者在您的情况下,因为您're using an oauth2 dependency, /oauth2/authorization/google
页面。然后循环无限继续下去。
在这种情况下,一个简单的解决方法是通过 .mvcMatchers("/error").permitAll()
或类似方式公开错误页面。值得考虑的是这是否有意义,或者这样做是否会暴露敏感信息。您可能希望使用另一种技术来处理某些错误,例如 Spring Boot.
中的 ErrorViewResolver
interface
如果请求中不存在某个 header,我需要阻止所有请求处理。因此,我有以下 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 引导仍将用户重定向到登录页面,如下输出所示:
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 安全所采用的 secure by default principle(参见示例 86)相结合。
由于您在响应中返回 401 状态代码,/error
视图在内部被调用,这导致第二次通过过滤器链。由于您的过滤器扩展了 OncePerRequestFilter
,因此不会在第二次调用它,使其看起来像是被跳过了。
随后,Spring 安全过滤器链的其余部分启动,检测到对 /error
视图的未授权访问,并重定向到 /login
,或者在您的情况下,因为您're using an oauth2 dependency, /oauth2/authorization/google
页面。然后循环无限继续下去。
在这种情况下,一个简单的解决方法是通过 .mvcMatchers("/error").permitAll()
或类似方式公开错误页面。值得考虑的是这是否有意义,或者这样做是否会暴露敏感信息。您可能希望使用另一种技术来处理某些错误,例如 Spring Boot.
ErrorViewResolver
interface