When loading the swagger-ui.html page, a request is made to host:port/ and host:port/csfr
Let me answer your questions one by one.
Why are the request made to
http://localhost:8080/
andhttp://localhost:8080/csrf
?
This is because, Springfox Swagger has by default enabled support for CSRF. What this does is, whenever you try to access any swagger endpoints in your application, it checks for the CSRF token in the below order and attaches it to the request header.
- CSRF token within your meta tags served at
/
- Endpoint
/csrf
- CSRF token within your cookie
The reason Springfox Swagger attaches the CSRF token is, in case your application has CSRF protection enabled, the requests to the swagger endpoints would fail in case they don't have the CSRF token as part of the header.
What kind of header/token is swagger expecting, and what will it do with the information in it?
As I told earlier, swagger is expecting a CSRF token and it'll attach it to the header of the request when you try to access any swagger endpoints.
Can I use this to make my app (or the swagger endpoint) more secure or accessible?
Enabling CSRF protection within your app would make your app secure from CSRF attacks and not necessarily just by providing the CSRF token to swagger to attach to the header. In case you have enabled CSRF protection within your app, you must provide the CSRF token by any of the above 3 means to access any swagger endpoints within your app. You can read about the use of enabling CSRF protection here.
I'm failing to find information on what to actually implement
There is no use of implementing the CSRF token provision for swagger if you have not enabled CSRF protection within your app, as it would just be redundant. But in case you want to implement the CSRF token provision for swagger you can do it by either of the 3 methods below:
1) CSRF token within your meta tags served at /
<html>
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>
This is in case you are using any templating mechanism like JSP, thymeleaf etc.
2) Endpoint /csrf
Define an endpoint /csrf
to provide the CSRF token.
@RequestMapping("/csrf")
public CsrfToken csrf() {
//logic to return the CSRF token
}
3) CSRF token within your cookie
The default cookie name searched for is XSRF-TOKEN
, and the default header name returned is X-XSRF-TOKEN
. Spring security provides a way of storing the CSRF token in the cookie as required by swagger with the configuration below
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
Implementing either of the above 3 would provide swagger with the CSRF token to attach to the request header.
The reference to the above is from the GitHub PR which provided the CSRF support to Springfox swagger and also Spring security documentation which I have linked earlier.
There is currently an open issue regarding the default enabled CSRF support here, and couple of open PRs with the fix #2639 and #2706.
Depending on 2) Endpoint /csrf
In my case I disabled WebSecurity until yet and also get the 404 Error Code for /csrf. I fixed that with a simple Controller as mentioned above. Here is my Controller:
@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));
}
}
If you use that, you need to add the maven dependency for web security:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>