【问题标题】:When loading the swagger-ui.html page, a request is made to host:port/ and host:port/csfr在加载 swagger-ui.html 页面时,向 host:port/ 和 host:port/csfr 发出请求
【发布时间】:2019-04-08 21:28:07
【问题描述】:

我有一个 Spring boot 2 应用程序(rest API)并使用 Springfox Swagger 2 库,包括 UI 库。当我打开在http://localhost:8080/swagger-ui.html 找到的招摇界面时,一切都按预期工作,但是发出了两个请求,在记录器中给出了 404 结果:

http://localhost:8080/(没有任何东西映射到我的应用程序的根目录)
http://localhost:8080/csfr(这个映射也不存在,但我知道它存在 对于“跨站点伪造请求”)

显然,Swagger 这样做是因为它“支持”某种 csfr 令牌检查,如 explained here。现在有几个月的调查是否可以配置这些 404 调用,所以我现在正在考虑实施端点。我无法找到有关最终实施的信息。大摇大摆地期待什么样的标头/令牌,它将如何处理其中的信息?我可以使用它来使我的应用程序(或 swagger 端点)更安全或更易于访问吗?简而言之:有什么意义:)?

【问题讨论】:

  • 你能分享两个给出404的API的源代码吗?
  • swagger-ui用api能看吗,也请分享相关代码
  • 我想,也许,您的意思是“.. 向 host:port/csrf 发出请求”而不是 csfr :)

标签: java spring-boot swagger swagger-ui springfox


【解决方案1】:

让我一一回答你的问题。

为什么向http://localhost:8080/提出请求和 http://localhost:8080/csrf?

这是因为 Springfox Swagger 默认启用了对 CSRF 的支持。它的作用是,每当您尝试访问应用程序中的任何 swagger 端点时,它都会按以下顺序检查 CSRF 令牌并将其附加到请求标头。

  • 您的元标记中的 CSRF 令牌在 / 提供
  • 端点/csrf
  • 您的 cookie 中的 CSRF 令牌

Springfox Swagger 附加 CSRF 令牌的原因是,如果您的应用程序启用了 CSRF 保护,那么对 swagger 端点的请求将失败,以防它们没有 CSRF 令牌作为标题。

swagger 期待什么样的 header/token,它将如何处理其中的信息?

正如我之前所说,swagger 需要一个 CSRF 令牌,当您尝试访问任何 swagger 端点时,它会将其附加到请求的标头中。

我可以使用它来使我的应用程序(或 swagger 端点)更安全或更易于访问吗?

在您的应用中启用 CSRF 保护将使您的应用免受 CSRF 攻击,而不一定只是通过提供 CSRF 令牌来大摇大摆地附加到标头。如果您在应用中启用了 CSRF 保护,则必须通过上述 3 种方式中的任何一种提供 CSRF 令牌,以访问应用中的任何 swagger 端点。您可以阅读有关启用 CSRF 保护的使用here

我找不到有关实际实施的信息

如果你没有在你的应用程序中启用 CSRF 保护,那么为 swagger 实现 CSRF 令牌提供是没有用的,因为它只是多余的。但是,如果您想为 swagger 实施 CSRF 令牌规定,您可以通过以下 3 种方法之一来实现:

1) 在 / 提供的元标记中的 CSRF 令牌

<html>
<head>
  <meta name="_csrf" content="${_csrf.token}"/>
  <!-- default header name is X-CSRF-TOKEN -->
  <meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>

这是在您使用任何模板机制(如 JSP、thymeleaf 等)的情况下。

2) 端点/csrf

定义一个端点 /csrf 以提供 CSRF 令牌。

  @RequestMapping("/csrf")
  public CsrfToken csrf() {
    //logic to return the CSRF token
  }

3) Cookie 中的 CSRF 令牌

搜索的默认cookie名称为XSRF-TOKEN,返回的默认标头名称为X-XSRF-TOKEN。 Spring Security 提供了一种将 CSRF 令牌存储在 cookie 中的方式,按照 swagger 的要求,配置如下

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
}

实现上述 3 中的任何一个都会提供带有 CSRF 令牌以附加到请求标头的 swagger。

对上述内容的引用来自GitHub PR,它为 Springfox swagger 提供了 CSRF 支持,以及我之前链接的 Spring 安全文档。

目前存在一个关于默认启用的 CSRF 支持 here 的未解决问题,以及修复 #2639#2706 的几个开放 PR。

【讨论】:

  • 您说:“这是因为 Springfox Swagger 默认启用了对 CSRF 的支持。”有没有办法禁用此支持,因此不再发出请求,因此 404 将不再发生?
  • @user1884155 恐怕目前没有办法禁用 CSRF 支持。我已经在我的回答中添加了相关问题并打开了相同的 PR。
  • @MadhuBhat 但是如果CSRF值通过index或者/csrf暴露出来,是不是又会打开漏洞攻击呢?
  • @VukDjapic 不知何故我错过了回答你的问题。本质上在生产级应用程序中,它可以位于 API 网关之后,这样它就不会暴露在外部,因此不会获得任何外部流量。
【解决方案2】:

取决于 2) 端点 /csrf

在我的情况下,我一直禁用 WebSecurity,并且还获得了 /csrf 的 404 错误代码。我用上面提到的一个简单的控制器解决了这个问题。这是我的控制器:

@Controller
public class CSRFController {
    @RequestMapping(value = "/csrf", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public ResponseEntity<CsrfToken> getToken(final HttpServletRequest request) {
        return ResponseEntity.ok().body(new HttpSessionCsrfTokenRepository().generateToken(request));
    }

}

如果你使用它,你需要为 web 安全添加 maven 依赖:

<dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-web</artifactId>
 </dependency>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2019-06-03
    • 2014-02-24
    • 1970-01-01
    • 2019-02-12
    相关资源
    最近更新 更多