javascript angular spring-boot cors httprequest

javascript - Código de estado HTTP 401 a pesar de que estoy enviando credenciales en la solicitud



angular spring-boot (1)

Recientemente he introducido la autenticación JWT en mi aplicación basada en Springboot y Angualr2. Allí intenté hacer una solicitud POST pasando el token JWT como se muestra a continuación en mi código Angualr

save(jobId: number, taskId: number, note: Note) { return this.http.post(environment.APIENDPOINT + ''/jobs/'' + jobId + ''/tasks/'' + taskId + ''/notes'', note, this.setHeaders()).map((response: Response) => response.json()); }

private setHeaders() { // create authorization header with jwt token let currentUser = JSON.parse(localStorage.getItem(''currentUser'')); console.log("Current token---"+ currentUser.token); if (currentUser && currentUser.token) { let headers = new Headers(); headers.append(''Content-Type'', ''application/json''); headers.append(''authorization'',''Bearer ''+ currentUser.token); let r = new RequestOptions({ headers: headers }) return r; } }

Sin embargo, en el lado del servidor, devuelve el código de estado 401. El problema está en el lado de Springboot, comprueba el encabezado de autorización como se muestra a continuación y devuelve nulo

String authToken = request.getHeader("authorization ");

Luego eché un vistazo al encabezado de la solicitud y tiene el encabezado de autorización en Access-Control-Request-Headers como se muestra a continuación. Pero no es visible para el lado del servidor.

Luego leí más y descubrí que esto podría ser un problema con la configuración de CORS. Así que modifiqué mi filtro de configuración CORS para agregar addExposedHeader como se muestra a continuación

@Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addExposedHeader("authorization"); config.addAllowedMethod("OPTIONS"); config.addAllowedMethod("GET"); config.addAllowedMethod("POST"); config.addAllowedMethod("PUT"); config.addAllowedMethod("DELETE"); //config.addExposedHeader("Content-Type"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); }

Aún así, el servidor se queja de que no puede encontrar el encabezado de autorización. ¿Extrañé algo aquí? Aprecio tu ayuda

Solución

Después de leer el comentario de sidehowbarker a continuación, pude entender los conceptos básicos detrás del problema. En My Project tengo un filtro de token JWT y dentro de él siempre verifica el encabezado de autorización. Luego lo he modificado como a continuación y ahora funciona como se esperaba

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { try { if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); }else{ String authToken = request.getHeader(this.tokenHeader); jWTTokenAuthenticationService.parseClaimsFromToken(authToken); -- } chain.doFilter(request, response); }Catch(AuthenticationException authEx){ SecurityContextHolder.clearContext(); if (entryPoint != null) { entryPoint.commence(request, response, authEx); } }

}


Debe configurar el servidor para que no requiera autorización para las solicitudes de OPTIONS (es decir, el servidor al que se envía la solicitud, no el que sirve su código de interfaz).

Eso es porque lo que está sucediendo es esto:

  1. Su código le indica a su navegador que desea enviar una solicitud con el encabezado de Authorization .
  2. Su navegador dice, OK, las solicitudes con el encabezado de Authorization requieren que haga una OPCIÓN de verificación previa de CORS para asegurarme de que el servidor permita solicitudes con el encabezado de Authorization .
  3. Su navegador envía la solicitud de OPTIONS al servidor sin el encabezado de Authorization , porque todo el propósito de la verificación de OPTIONS es ver si está bien incluir ese encabezado.
  4. Su servidor ve la solicitud de OPTIONS pero en lugar de responder de una manera que indica que permite el encabezado de Authorization en las solicitudes, la rechaza con un 401 ya que carece del encabezado.
  5. Su navegador espera una respuesta de 200 o 204 para la verificación previa CORS, pero en cambio obtiene esa respuesta 401. Por lo tanto, su navegador se detiene allí y nunca intenta la solicitud POST de su código.

Más detalles:

Los Access-Control-Request-Headers y Access-Control-Request-Method en la captura de pantalla de la pregunta indican que el navegador está haciendo una solicitud de OPC de verificación previa de CORS .

Y la presencia de la Authorization y Content-Type: application/json encabezados de solicitud de Content-Type: application/json en su solicitud son los que hacen que su navegador haga la verificación previa de CORS, al enviar una solicitud de OPTIONS al servidor antes de intentar la solicitud POST en su código. Y debido a que la OPTIONS previa de OPTIONS falla, el navegador se detiene allí y nunca intenta la POST .

Por lo tanto, debe averiguar a qué parte del código actual del lado del servidor en el servidor al que se envía la solicitud hace que requiera autorización para las solicitudes de OPTIONS , y cambiar eso para que responda a OPTIONS con una respuesta exitosa de 200 o 204 sin autorización siendo requerido

Para obtener ayuda específica sobre cómo hacer eso para un servidor Spring en particular, consulte las siguientes respuestas: