CORS: el modo de credenciales es 'incluir'

100

Sí, sé lo que estás pensando, otra pregunta de CORS, pero esta vez estoy perplejo.

Entonces, para comenzar, el mensaje de error real:

XMLHttpRequest no puede cargar http: //localhost/Foo.API/token . El valor del encabezado 'Access-Control-Allow-Origin' en la respuesta no debe ser el comodín '*' cuando el modo de credenciales de la solicitud es 'incluir' . Por lo tanto, no se permite el acceso al origen ' http: // localhost: 5000 '. El modo de credenciales de las solicitudes iniciadas por XMLHttpRequest está controlado por el atributo withCredentials.

No estoy seguro de lo que significa que el modo de credenciales es 'incluir' .

Así que cuando realizo la solicitud de cartero, experimento ningún error de este tipo:

ingrese la descripción de la imagen aquí

Pero cuando accedo a la misma solicitud a través de mi aplicación web angularjs, este error me desconcierta. Aquí está mi solicitud / respuesta de angualrjs. Como verá, la respuesta es OK 200, pero sigo recibiendo el error CORS:

Solicitud y respuesta de Fiddler:

La siguiente imagen muestra la solicitud y la respuesta del front-end web a la API

Violinista

Entonces, según todas las otras publicaciones que he leído en línea, parece que estoy haciendo lo correcto, por eso no puedo entender el error. Por último, aquí está el código que uso dentro de angualrjs (fábrica de inicio de sesión):

ingrese la descripción de la imagen aquí

Implementación de CORS en API - Fines de referencia:

Método 1 utilizado:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("*", "*", "*")
        {
            SupportsCredentials = true
        };
        config.EnableCors(cors);
    }
}

Método 2 utilizado:

public void Configuration(IAppBuilder app)
{
    HttpConfiguration config = new HttpConfiguration();

    ConfigureOAuth(app);

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

}

¡Muchas gracias de antemano!

Richard Bailey
fuente
bonitas fotos, de que son? Para responder a su pregunta, si incluye autenticación, la respuesta de acceso-control-permitir-origen debe ser el host de origen (página del navegador), no puede ser *, entonces, el lado del servidor está haciendo CORS mal, oh, y el cartero funciona porque no es una solicitud de origen cruzado
Jaromanda X
@JaromandaX, gracias por la respuesta. Las imágenes demuestran la solicitud / respuesta, así como demuestran los encabezados que se pasan. Usted hace la pregunta, obviamente dice que no logró su objetivo ...
Richard Bailey
Mi comentario debería ser todo lo que necesita saber - no necesitaba ver las fotos
Jaromanda X
Recientemente, decidí alejarme de las cookies en mi API web y hacer uso de tokens. Cuando utilicé cookies, mi CORS funciona sin problemas. Así que estoy luchando por entender cómo CORS no se implementa correctamente en el lado del servidor
Richard Bailey
1
si incluye autenticación, la access-control-allow-originrespuesta debe ser el host de origen (página del navegador), no puede ser*
Jaromanda X

Respuestas:

103

El problema proviene de su código Angular:

Cuando withCredentialsse establece en verdadero, está intentando enviar credenciales o cookies junto con la solicitud. Como eso significa que otro origen está intentando realizar solicitudes autenticadas, el comodín ("*") no está permitido como encabezado "Access-Control-Allow-Origin".

Debería responder explícitamente con el origen que hizo la solicitud en el encabezado "Access-Control-Allow-Origin" para que esto funcione.

Recomendaría incluir explícitamente en la lista blanca los orígenes que desea permitir para realizar solicitudes autenticadas, porque simplemente responder con el origen de la solicitud significa que cualquier sitio web puede realizar llamadas autenticadas a su backend si el usuario tiene una sesión válida.

Explico estas cosas en este artículo que escribí hace un tiempo.

Por lo tanto, puede configurarlo withCredentialsen falso o implementar una lista blanca de origen y responder a las solicitudes CORS con un origen válido siempre que haya credenciales involucradas

geekonauta
fuente
3
Estoy trabajando en la aplicación Angular 5 con TypeScript. Necesito dar withCredentials como verdadero; de lo contrario, obtendré la excepción de autorización fallida. Cómo resolver esto con Credenciales: verdadero
Ziggler
@Ziggler Tuve la misma situación. ¿Encuentra soluciones?
Pavel
@Ziggler Multado solución vea mi respuesta.
Pavel
1
Sigo recibiendo este error cuando uso WithCredentials = TRUE y Access-Control-Allow-Origin = [' localhost: 4200'] , y NO estoy usando star * por lo que el mensaje de error ya no tiene sentido. MENSAJE DE ERROR: "La respuesta a la solicitud de verificación previa no pasa la verificación de control de acceso: el valor del encabezado 'Access-Control-Allow-Origin' en la respuesta no debe ser el comodín * cuando el modo de credenciales de la solicitud es 'incluir'. Origen Por tanto, no se permite el acceso a ' localhost: 4200 '. El modo de credenciales de las solicitudes iniciadas por XMLHttpRequest está controlado por el atributo withCredentials ".
mruanova
@mruanova, ¿está seguro de que el encabezado Access-Control-Allow-Origin está configurado correctamente en la solicitud? Parece que algo se envía con un comodín en algún lugar
geekonaut
14

Si está utilizando middleware CORS y desea enviar withCredentialsboolean true, puede configurar CORS de esta manera:

var cors = require('cors');    
app.use(cors({credentials: true, origin: 'http://localhost:5000'}));

'

Ankur Kedia
fuente
11

Personalización de CORS para Angular 5 y Spring Security (solución basada en cookies)

En el lado angular, se requiere agregar un indicador de opción withCredentials: truepara el transporte de cookies:

constructor(public http: HttpClient) {
}

public get(url: string = ''): Observable<any> {
    return this.http.get(url, { withCredentials: true });
}

En el lado del servidor de Java, se requiere agregar CorsConfigurationSourcepara la configuración de la política CORS:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        // This Origin header you can see that in Network tab
        configuration.setAllowedOrigins(Arrays.asList("http:/url_1", "http:/url_2")); 
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        configuration.setAllowedHeaders(Arrays.asList("content-type"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
}

El método configure(HttpSecurity http)por defecto se utilizará corsConfigurationSourceparahttp.cors()

Pavel
fuente
1

Si ayuda, estaba usando centrifuge con mi aplicación reactjs y, después de revisar algunos comentarios a continuación, miré el archivo de biblioteca centrifuge.js, que en mi versión tenía el siguiente fragmento de código:

if ('withCredentials' in xhr) {
 xhr.withCredentials = true;
}

Después de eliminar estas tres líneas, la aplicación funcionó bien, como se esperaba.

¡Espero eso ayude!

Gustavo garcia
fuente
1

Si está utilizando .NET Core, tendrá que .AllowCredentials () al configurar CORS en Startup.CS.

Dentro de ConfigureServices

services.AddCors(o => {
    o.AddPolicy("AllowSetOrigins", options =>
    {
        options.WithOrigins("https://localhost:xxxx");
        options.AllowAnyHeader();
        options.AllowAnyMethod();
        options.AllowCredentials();
    });
});

services.AddMvc();

Luego, dentro de Configure:

app.UseCors("AllowSetOrigins");
app.UseMvc(routes =>
    {
        // Routing code here
    });

Para mí, fue específicamente la falta de options.AllowCredentials () lo que causó el error que mencionaste. Como nota al margen en general para otros que también tienen problemas con CORS, el orden es importante y AddCors () debe registrarse antes que AddMVC () dentro de su clase de inicio.

Steven Pfeifer
fuente