Solución:
Déjame responder tus preguntas una por una.
¿Por qué se hace la solicitud a
http://localhost:8080/
y
http://localhost:8080/csrf
?
Esto se debe a que Springfox Swagger tiene habilitado de forma predeterminada el soporte para CSRF. Lo que hace esto es que, cada vez que intenta acceder a cualquier punto final de swagger en su aplicación, verifica el token CSRF en el orden a continuación y lo adjunta al encabezado de la solicitud.
- Token CSRF dentro de sus metaetiquetas servidas en
/
- Punto final
/csrf
- Token CSRF dentro de su cookie
La razón por la que Springfox Swagger adjunta el token CSRF es, en caso de que su aplicación tenga Protección CSRF habilitada, las solicitudes a los puntos finales swagger fallarían en caso de que no tuvieran el token CSRF como parte del encabezado.
¿Qué tipo de encabezado / token espera Swagger y qué hará con la información que contiene?
Como dije anteriormente, swagger espera un token CSRF y lo adjuntará al encabezado de la solicitud cuando intente acceder a cualquier punto final de swagger.
¿Puedo usar esto para hacer que mi aplicación (o el punto final de Swagger) sea más segura o accesible?
Habilitación de la protección CSRF dentro de su aplicación protegería su aplicación de ataques CSRF y no necesariamente solo proporcionando el token CSRF a swagger para adjuntarlo al encabezado. En caso de que haya habilitado la protección CSRF dentro de su aplicación, debe proporcione el token CSRF por cualquiera de los 3 medios anteriores para acceder a cualquier punto final de swagger dentro de su aplicación. Puede leer sobre el uso de habilitar la protección CSRF aquí.
No encuentro información sobre qué implementar realmente
No tiene sentido implementar la provisión de token CSRF para swagger si no ha habilitado la protección CSRF dentro de su aplicación, ya que sería redundante. Pero en caso de que desee implementar la provisión de token CSRF para swagger, puede hacerlo mediante cualquiera de los 3 métodos a continuación:
1) Token CSRF dentro de sus metaetiquetas servidas en /
<html>
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>
Esto es en caso de que esté utilizando algún mecanismo de plantillas como JSP, thymeleaf, etc.
2) Punto final /csrf
Definir un punto final /csrf
para proporcionar el token CSRF.
@RequestMapping("/csrf")
public CsrfToken csrf() {
//logic to return the CSRF token
}
3) token CSRF dentro de su cookie
El nombre de cookie predeterminado buscado es XSRF-TOKEN
, y el nombre de encabezado predeterminado devuelto es X-XSRF-TOKEN
. Spring Security proporciona una forma de almacenar el token CSRF en la cookie según lo requiera Swagger con la siguiente configuración.
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
}
La implementación de cualquiera de los 3 anteriores proporcionaría arrogancia con el token CSRF para adjuntar al encabezado de la solicitud.
La referencia a lo anterior es de GitHub PR que proporcionó el soporte CSRF para Springfox swagger y también la documentación de seguridad de Spring que he vinculado anteriormente.
Actualmente hay un problema abierto con respecto al soporte CSRF habilitado por defecto aquí, y un par de PR abiertos con la solución # 2639 y # 2706.
Dependiendo de 2) Endpoint / csrf
En mi caso, desactivé WebSecurity hasta ahora y también obtuve el código de error 404 para / csrf. Lo arreglé con un controlador simple como se mencionó anteriormente. Aquí está mi controlador:
@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));
}
}
Si usa eso, debe agregar la dependencia de maven para la seguridad web:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>