java Spring Boot 3:跳过内部重定向行为

rpppsulh  于 2022-12-21  发布在  Java
关注(0)|答案(1)|浏览(171)

升级到SpringBoot3后,我遇到了一个奇怪的行为。我有一个端点被外部服务调用,并返回302状态代码。请看下面的代码片段。

@GetMapping("/callback")
@Hidden
@SneakyThrows
public void callback(@NotNull @RequestParam(name = "code") String authorizationCode,
        @NotNull @RequestParam(name = "state") String state,
        HttpServletResponse httpResponse) {

    try {
        ...
        httpResponse.addCookie(jwtTokenCookie););
        httpResponse.sendRedirect(state.targetUri());
    } catch (IntegrationException e) {
        throw new ControllerException(BAD_REQUEST, e);
    }
}

问题是我不再接收302状态码了,取而代之的是Spring在内部执行实际的重定向,并返回targetUri()端点调用的结果,但我不希望这样,我需要接收302状态码和实际的重定向值。
我试着重构代码:

final var jwtTokenCookie = cookieService.createJwtCookie(userContext);httpResponse.addCookie(jwtTokenCookie);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setLocation(new URI(ssoState.targetUri()));
return new ResponseEntity<>(httpHeaders, FOUND);

但是它不起作用。看起来Spring Security注册了一些过滤器来检查所有的3xx响应。我能以某种方式关闭它吗?

编辑1

我还尝试调优TestRestTemplate示例来手动禁用可能的重定向。

testRestTemplate = new TestRestTemplate(
            restTemplateBuilder, null, null, TestRestTemplate.HttpClientOption.ENABLE_COOKIES
        );

如您所见,我没有传递HttpClientOption.ENABLE_REDIRECTS选项,因此TestRestTemplate应该返回结果,无论如何,我仍然得到重定向的URL响应值。
所以,我敢打赌,服务会重定向,但客户端不会。
以下是响应标头:

Cache-Control:"no-cache, no-store, max-age=0, must-revalidate",
Connection:"keep-alive",
Content-Type:"application/json;charset=UTF-8",
Date:"Tue, 29 Nov 2022 19:25:54 GMT",
Expires:"0",
Keep-Alive:"timeout=60",
Pragma:"no-cache",
Transfer-Encoding:"chunked",
Vary:"Origin",
"Access-Control-Request-Method",
"Access-Control-Request-Headers",
X-Content-Type-Options:"nosniff",
X-Frame-Options:"DENY",
X-XSS-Protection:"0"

请求标头为空。

编辑2

我还尝试将springdoc库升级到2.x.x
以前的版本是

implementation "org.springdoc:springdoc-openapi-ui:1.6.13"

新版本为

implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2"

无论如何,这并没有帮助。我还打开了跟踪日志以获取更多信息。看看下面的代码,看看我得到了什么。

21:10:42.223 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Using @ExceptionHandler ...SsoController#handleRedirectException(RedirectException)
21:10:42.223 TRACE o.s.w.m.HandlerMethod - Arguments: [...RedirectException: Redirect to /api/accounts]
21:10:42.224 DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Using 'text/plain', given [text/plain, application/json, application/*+json, */*] and supported [*/*]
21:10:42.224 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolved [...RedirectException: Redirect to /api/accounts]
21:10:42.224 TRACE o.s.w.s.DispatcherServlet - No view rendering, null ModelAndView returned.
21:10:42.225 DEBUG o.s.w.s.DispatcherServlet - Completed 302 FOUND, headers={masked}
21:10:42.225 TRACE o.s.s.w.h.w.HstsHeaderWriter - Not injecting HSTS header since it did not match request to [Is Secure]
21:10:42.228 TRACE o.s.s.w.FilterChainProxy - Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@45d1efc3, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@193e95a8, org.springframework.security.web.context.SecurityContextHolderFilter@2b359a0f, org.springframework.security.web.header.HeaderWriterFilter@5df041, org.springframework.web.filter.CharacterEncodingFilter@7b0eeb99, org.springframework.security.web.authentication.logout.LogoutFilter@31324b57, ...JwtAuthenticationFilter@504b132d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@387ee53c, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5cf6aa48, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1a2e5110, org.springframework.security.web.session.SessionManagementFilter@419ae2fd, org.springframework.security.web.access.ExceptionTranslationFilter@3fed07ba, org.springframework.security.web.access.intercept.AuthorizationFilter@6ce03f94]] (1/1)
21:10:42.228 DEBUG o.s.s.w.FilterChainProxy - Securing GET /api/accounts
21:10:42.228 TRACE o.s.s.w.FilterChainProxy - Invoking DisableEncodeUrlFilter (1/13)
21:10:42.229 TRACE o.s.s.w.FilterChainProxy - Invoking WebAsyncManagerIntegrationFilter (2/13)
21:10:42.229 TRACE o.s.s.w.FilterChainProxy - Invoking SecurityContextHolderFilter (3/13)
21:10:42.229 TRACE o.s.s.w.FilterChainProxy - Invoking HeaderWriterFilter (4/13)
21:10:42.229 TRACE o.s.s.w.FilterChainProxy - Invoking CharacterEncodingFilter (5/13)
21:10:42.229 TRACE o.s.s.w.FilterChainProxy - Invoking LogoutFilter (6/13)
...

正如您所看到的,有一些过滤器捕获302,并试图在内部继续重定向到/api/accounts,而不是简单地将状态代码返回给客户机。
根据日志,FilterChainProxy启动了不需要的重定向行为。然而,它不是一个具体的bean,而是一个在Spring组件中广泛使用的容器。有什么想法如何禁用内部重定向?

hgb9j2n6

hgb9j2n61#

你需要在路由处理中抛出你的异常,并通过发出代码http_code=302和http_text=redirect_bla_bla_bla来处理它。其次,你需要在重定向中使用OnlyIn交换模式。

相关问题