es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Encabezado de autorización faltante en Spring Boot CORS

Estoy desarrollando una aplicación utilizando Spring Boot en el backend y React en el frontend. Estoy teniendo algunos problemas con CORS y autorización: en particular, cuando hago una solicitud desde el frontend, agrego el encabezado Authorization que contiene el token JWT para la autenticación. Aquí hay un ejemplo del código:

async function getUserInfo (username) {
const url = baseURL + "/users/" + username
const jwt = sessionStorage.getItem('token')

let [err, response] = await to(fetch(url), {
    method: 'GET',
    headers: {
        'Authorization': 'Bearer ' + jwt,
        'Content-Type': 'application/json'
    }
})

...

}

Cuando la solicitud llega al backend, falta este encabezado y la autenticación falla. Para configurar CORS en Spring Boot, uso la anotación @CrossOrigin:

@CrossOrigin(origins = ["*"], allowedHeaders = ["*"], exposedHeaders = ["*"])
@RestController
class UserController (
    val userDetailsService: UserDetailsServiceImpl,
    val authenticationManager: AuthenticationManager,
    val jwtUtils: JwtUtils
) {

...

}

La configuración de seguridad es la siguiente:

override fun configure(http: HttpSecurity) {
    //csrf está habilitado de forma predeterminada
    http.cors().and().csrf().disable()
        .exceptionHandling().authenticationEntryPoint(authEntryPoint)
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers("/auth/**")
        .permitAll()
        .and()
        .authorizeRequests()
        .antMatchers("/users/{username}/**")
        .hasAuthority("ADMIN")
        .and()
        .authorizeRequests()
        .antMatchers("/**")
        .hasAuthority("CUSTOMER")
        .and()
        .logout()
        .permitAll()

    http.addFilterBefore(JwtAuthenticationTokenFilter(jwtUtils),
        UsernamePasswordAuthenticationFilter::class.java)
}

Las solicitudes se realizan utilizando un usuario ADMIN en el endpoint /users/{username}, como se muestra en el código del frontend.

¿Cómo puedo resolver este problema?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para resolver este problema, es necesario agregar la anotación @CrossOrigin a la clase controladora de Spring Boot para permitir que las solicitudes de la aplicación frontend accedan al backend. La anotación @CrossOrigin especifica qué dominios tienen permitido hacer solicitudes al backend, así como qué cabeceras tienen permitido ser enviadas con las solicitudes.

    Además, es necesario agregar el campo allowedHeaders a la anotación @CrossOrigin con Authorization como valor para permitir que la cabecera Authorization sea enviada con las solicitudes. Su anotación actualizada @CrossOrigin debería lucir así:

    @CrossOrigin(origins = ["*"], allowedHeaders = ["*","Authorization"], exposedHeaders = ["*"])
    @RestController
    class UserController (
        val userDetailsService: UserDetailsServiceImpl,
        val authenticationManager: AuthenticationManager,
        val jwtUtils: JwtUtils
    ) {
    
    ...
    
    }
    

    Adicionalmente, es necesario actualizar la configuración de seguridad para permitir explícitamente la cabecera Authorization. Esto se puede hacer agregando la siguiente línea de código al método configure:

    http.headers().frameOptions().disable().and().authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
    

    Este código permite que las solicitudes OPTIONS sean realizadas sin autenticación ni autorización, lo cual es necesario para que funcionen las solicitudes previas de CORS.

    Finalmente, asegúrese de probar su código actualizado minuciosamente para asegurarse de que los problemas de CORS y autorización hayan sido resueltos.

Comments are closed.