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.

La solicitud de publicación de Spring Boot Security no funciona con CORS.

Estoy utilizando el framework Spring Boot, he implementado dos puntos finales REST de tipo GET y tipo POST.
Las solicitudes GET y POST funcionan bien si se acceden desde la misma origen.
Cuando intento acceder a esos puntos finales desde una aplicación React, la solicitud GET funciona bien, pero cuando hago la segunda solicitud (solicitud POST) obtengo el código de estado 401. No pude encontrar ningún error de CORS en la consola del navegador.
Código del frontend.

const _HEADERS = {
    'Content-Type': 'application/json',
    'x-xsrf-token': getCSRFToken(),
    'Authorization': 'Basic ' + btoa("admin" + ":" + "admin")
}

let fetchData = async (resource:string, method:string, postData:Object, mode:string = SAME_ORGIN, formData:any = null, headers:any = _HEADERS ) => {
    let initObj = {};
    if( method === "GET" ) {
        initObj = {
            method: method,
            mode: mode,
            cache: 'no-cache',
            headers: headers
          };
    } else {
        initObj = {
            method: method,
            mode: mode,
            cache: 'no-cache',
            headers: headers,
            body: formData === null? JSON.stringify(postData): formData
        };
    }

    return await fetch( new Request(resource, initObj) );
}

Backend code

Global cors
@Bean
public WebMvcConfigurer configure() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
Boolean corsEnabled = Boolean.parseBoolean( environment.getProperty(“application.cors.enabled”));
if( corsEnabled != null && corsEnabled == true ) {
registry.addMapping(“/**”).allowedOrigins(“http://localhost:8000”);
}
}
};
}

Security
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().authorizeRequests((requests) -> requests.anyRequest().authenticated());
http.formLogin();
http.httpBasic();
if (corsEnabled != null && corsEnabled == true) {
http.cors();
}

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar relacionado con el intercambio de recursos de origen cruzado (CORS). Aunque el código backend incluye una configuración de CORS que permite las solicitudes desde “http://localhost:8000”, el problema aún ocurre al intentar acceder al segundo endpoint (solicitud POST) desde la aplicación de React.

    Una posible solución es asegurarse de que el código frontend incluya las cabeceras CORS adecuadas al realizar la solicitud. Específicamente, la cabecera “Access-Control-Allow-Origin” debería incluir el dominio u origen de la aplicación de React (en este caso, “http://localhost:8000”). Además, la cabecera “Access-Control-Allow-Credentials” debe establecerse como “true” al utilizar cookies para la autenticación.

    Para lograr esto, el código backend debe actualizarse de la siguiente manera:

    Global cors
    @Bean
    public WebMvcConfigurer configure() {
        return new WebMvcConfigurer() {
            @Override
            public void  addCorsMappings(CorsRegistry registry) {
                Boolean corsEnabled = Boolean.parseBoolean(environment.getProperty("application.cors.enabled"));
                if (corsEnabled != null && corsEnabled == true) {
                    registry.addMapping("/**")
                            .allowedOrigins("http://localhost:8000")
                            .allowedMethods("*")
                            .allowCredentials(true); // Agregar esta línea para permitir credenciales
                }
            }
        };
    }
    
    Security
    http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and().authorizeRequests((requests) -> requests.anyRequest().authenticated());
    http.formLogin();
    http.httpBasic();
    if (corsEnabled != null && corsEnabled == true) {
        http.cors();
    }
    

    Ten en cuenta la adición de .allowCredentials(true) en la configuración de CORS.

    El código frontend también se puede actualizar para incluir las cabeceras adecuadas al realizar la solicitud:

    const _HEADERS = {
        'Content-Type': 'application/json',
        'x-xsrf-token': getCSRFToken(),
        'Authorization': 'Basic ' + btoa("admin" + ":" + "admin"),
        'Access-Control-Allow-Origin': 'http://localhost:8000',
        'Access-Control-Allow-Credentials': true // Agregar esta línea para permitir credenciales
    }
    
    let fetchData = async (resource:string, method:string, postData:Object, mode:string = _SAME_ORGIN, formData:any = null, headers:any = _HEADERS ) => {
        let initObj = {};
        if (method === "GET") {
            initObj = {
                method: method,
                mode: mode,
                cache: 'no-cache',
                headers: headers
            };
        } else {
            initObj = {
                method: method,
                mode: mode,
                cache: 'no-cache',
                headers: headers,
                body: formData === null? JSON.stringify(postData): formData
            };
        }
    
        return await fetch(new Request(resource, initObj));
    }
    

    Ten en cuenta la adición de las cabeceras “Access-Control-Allow-Origin” y “Access-Control-Allow-Credentials” en el objeto _HEADERS.

    Después de actualizar tanto el código frontend como el backend, la aplicación de React debería poder acceder al segundo endpoint (solicitud POST) sin recibir un error 401.

Comments are closed.