让我一个一个回答你的问题。
为什么会向 http://localhost:8080/
和 http://localhost:8080/csrf
发出请求?
这是因为,Springfox Swagger 默认启用了 CSRF 支持。这意味着,当您尝试访问应用程序中的任何 Swagger 端点时,它会按照以下顺序检查 CSRF 标记,并将其附加到请求头中。
- 位于
/
的 meta 标签中的 CSRF token
- 端点
/csrf
- 位于 cookie 中的 CSRF token
Springfox Swagger 附加 CSRF 标记的原因是,在您的应用程序启用了 CSRF 保护的情况下,如果 Swagger 的请求头中没有 CSRF 标记,则访问 Swagger 端点的请求将失败。
Swagger 预期哪种类型的标头/令牌,并会对其中的信息进行什么操作?
正如我之前所说,Swagger 预期一个 CSRF token,并在您尝试访问任何 Swagger 端点时将其附加到请求头中。
我可以使用此功能使我的应用程序(或 Swagger 端点)更安全或更易访问吗?
在您的应用程序中启用 CSRF 保护 可以使应用程序免受 CSRF 攻击,并不仅仅是通过提供 CSRF token 给 Swagger 附加到请求头中。如果您已经在应用程序中启用了 CSRF 保护,则必须通过上述任一方法之一提供 CSRF token 才能访问应用程序中的任何 Swagger 端点。您可以在此处阅读有关启用 CSRF 保护的用法。
我找不到实际实现的信息
如果您尚未在应用程序中启用 CSRF 保护,那么实现 Swagger 的 CSRF token 提供就没有任何用处,因为它将是多余的。但是,如果您想要实现 Swagger 的 CSRF token 提供,则可以使用以下三种方法之一:
1) 位于 /
的 meta 标签中的 CSRF token
<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() {
}
3) 在您的cookie中使用CSRF令牌
默认搜索的cookie名称是XSRF-TOKEN
,默认返回的标头名称是X-XSRF-TOKEN
。Spring Security提供了一种在cookie中存储CSRF令牌的方法,符合swagger的要求,使用以下配置即可。
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
实施以上三种方法之一将为Swagger提供CSRF token以附加到请求头中。
上述内容参考自GitHub PR,该PR为Springfox Swagger提供了CSRF支持,并且我之前链接的Spring Security文档也有相应说明。
目前存在一个关于默认启用CSRF支持的问题here,同时还有几个修复的开放性PR#2639和#2706。