CORS: Der Anmeldeinformationsmodus ist "Einschließen".

96

Ja, ich weiß, was Sie denken - noch eine CORS-Frage, aber diesmal bin ich ratlos.

Um zu beginnen, die eigentliche Fehlermeldung:

XMLHttpRequest kann http: //localhost/Foo.API/token nicht laden . Der Wert des Headers 'Access-Control-Allow-Origin' in der Antwort darf nicht der Platzhalter '*' sein, wenn der Anmeldeinformationsmodus der Anforderung 'include' ist . Origin ' http: // localhost: 5000 ' ist daher kein Zugriff gestattet. Der Anmeldeinformationsmodus von Anforderungen, die von XMLHttpRequest initiiert wurden, wird durch das Attribut withCredentials gesteuert.

Ich bin nicht sicher, was unter Anmeldeinformationsmodus "Einschließen" zu verstehen ist.

Wenn ich also die Anfrage beim Postboten ausführe, tritt kein solcher Fehler auf:

Geben Sie hier die Bildbeschreibung ein

Wenn ich jedoch über meine AngularJS-Webanwendung auf dieselbe Anfrage zugreife, bin ich von diesem Fehler überrascht. Hier ist meine angualrjs Anfrage / Antwort. Wie Sie sehen werden, lautet die Antwort OK 200, aber ich erhalte immer noch den CORS-Fehler:

Fiddler Anfrage und Antwort:

Das folgende Bild zeigt die Anforderung und Antwort vom Web-Front-End an die API

Geiger

Basierend auf all den anderen Posts, die ich online gelesen habe, scheint es , als würde ich das Richtige tun. Deshalb kann ich den Fehler nicht verstehen. Zum Schluss hier der Code, den ich in angualrjs (Login Factory) verwende:

Geben Sie hier die Bildbeschreibung ein

CORS-Implementierung in API - Referenzzwecke:

Methode 1 verwendet:

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);
    }
}

Methode 2 verwendet:

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

    ConfigureOAuth(app);

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

}

Vielen Dank im Voraus!

Richard Bailey
quelle
schöne bilder, wovon sind sie? Um Ihre Frage zu beantworten: Wenn Sie die Authentifizierung einschließen, muss die Antwort für die Zugriffskontrolle und den Ursprung zulassen der Ursprungshost (Browserseite) sein. Dies kann nicht sein *- also macht die Serverseite CORS falsch - oh, und der Postbote funktioniert, weil Es ist keine Cross-Origin-Anfrage
Jaromanda X
@ JaromandaX, danke für die Antwort. Die Bilder zeigen die Anforderung / Antwort sowie die übergebenen Header. Wenn Sie die Frage stellen, heißt es offensichtlich, dass das Ziel nicht erreicht wurde ...
Richard Bailey
Mein Kommentar sollte alles sein, was Sie wissen müssen - musste die Bilder nicht sehen
Jaromanda X
Vor kurzem habe ich beschlossen, mich von Cookies in meiner Web-API zu entfernen und eher Token zu verwenden. Wenn ich Cookies verwendet habe, funktioniert mein CORS ohne Probleme. Daher habe ich Probleme zu verstehen, dass CORS auf der Serverseite nicht korrekt implementiert ist
Richard Bailey,
1
Wenn Sie Authentifizierung einschließen, access-control-allow-originmuss die Antwort der Ursprungshost (Browserseite) sein, es kann nicht sein*
Jaromanda X

Antworten:

98

Das Problem ergibt sich aus Ihrem Angular-Code:

Wenn withCredentialstrue festgelegt ist, wird versucht, Anmeldeinformationen oder Cookies zusammen mit der Anforderung zu senden. Da dies bedeutet, dass ein anderer Ursprung möglicherweise versucht, authentifizierte Anforderungen auszuführen, ist der Platzhalter ("*") als Header "Access-Control-Allow-Origin" nicht zulässig.

Sie müssten explizit mit dem Ursprung antworten, der die Anforderung im Header "Access-Control-Allow-Origin" gestellt hat, damit dies funktioniert.

Ich würde empfehlen, die Ursprünge, die Sie für authentifizierte Anfragen zulassen möchten, explizit auf die Whitelist zu setzen, da eine einfache Beantwortung des Ursprungs der Anfrage bedeutet, dass jede Website authentifizierte Anrufe an Ihr Backend tätigen kann, wenn der Benutzer zufällig eine gültige Sitzung hat.

Ich erkläre dieses Zeug in diesem Artikel, den ich vor einiger Zeit geschrieben habe.

Sie können also entweder withCredentialsauf false setzen oder eine Ursprungs-Whitelist implementieren und auf CORS-Anfragen mit einem gültigen Ursprung antworten, wenn Anmeldeinformationen betroffen sind

Geekonaut
quelle
2
Ich arbeite an einer Angular 5-Anwendung mit TypeScript. Ich muss withCredentials als wahr angeben, sonst erhalte ich die Ausnahme "Autorisierung fehlgeschlagen". Wie man dies mit Credentials löst: true
Ziggler
@ Ziggler Ich hatte die gleiche Situation. Finden Sie Lösungen?
Pavel
@Ziggler Ich habe eine Geldstrafe verhängt, siehe meine Antwort.
Pavel
1
Ich erhalte immer noch diesen Fehler, wenn ich WithCredentials = TRUE und Access-Control-Allow-Origin = [' localhost: 4200'] verwende , und ich verwende NICHT star *, sodass die Fehlermeldung keinen Sinn mehr ergibt. FEHLERMELDUNG: "Antwort auf Preflight-Anforderung besteht nicht die Zugriffskontrollprüfung: Der Wert des Headers 'Access-Control-Allow-Origin' in der Antwort darf nicht der Platzhalter * sein, wenn der Anmeldeinformationsmodus der Anforderung 'include' lautet. Origin ' localhost: 4200 ' ist daher kein Zugriff gestattet. Der Anmeldeinformationsmodus von Anforderungen, die von XMLHttpRequest initiiert wurden, wird durch das Attribut withCredentials gesteuert. "
Mruanova
@mruanova Sind Sie sicher, dass der Header Access-Control-Allow-Origin in der Anforderung korrekt festgelegt ist? Es hört sich so an, als würde irgendwo etwas mit einer Wildcard gesendet
Geekonaut
12

Wenn Sie CORS-Middleware verwenden und withCredentialsboolean true senden möchten , können Sie CORS folgendermaßen konfigurieren:

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

`

Ankur Kedia
quelle
3
Lebensretter Antwort. +1 dafür
Nisharg Shah
1
Ich habe den ganzen Tag versucht, dieses Problem zu lösen. Du bist der Retter!
Hasan Sefa Ozalp
11

Anpassen von CORS für Angular 5 und Spring Security (Cookie-Basislösung)

Auf der Winkelseite muss das Optionsflag withCredentials: truefür den Cookie-Transport hinzugefügt werden:

constructor(public http: HttpClient) {
}

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

Auf der Java-Serverseite muss CorsConfigurationSourcefür die Konfiguration eine CORS-Richtlinie hinzugefügt werden:

@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()...
    }
}

Die Methode configure(HttpSecurity http)wird standardmäßig corsConfigurationSourcefür verwendethttp.cors()

Pavel
quelle
1

Wenn Sie .NET Core verwenden, müssen Sie beim Konfigurieren von CORS in Startup.CS .AllowCredentials () verwenden.

Innerhalb von ConfigureServices

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

services.AddMvc();

Dann innerhalb von Configure:

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

Für mich fehlten speziell nur options.AllowCredentials (), die den von Ihnen erwähnten Fehler verursachten. Als Randnotiz für andere, die ebenfalls CORS-Probleme haben, müssen die Ordnungsangelegenheiten und AddCors () vor AddMVC () in Ihrer Startup-Klasse registriert werden.

Steven Pfeifer
quelle
0

Wenn es hilft, habe ich centrifuge mit meiner reactjs-App verwendet. Nachdem ich einige Kommentare unten überprüft hatte, habe ich mir die Bibliotheksdatei centrifuge.js angesehen, die in meiner Version den folgenden Codeausschnitt enthielt:

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

Nachdem ich diese drei Zeilen entfernt hatte, funktionierte die App wie erwartet einwandfrei.

Ich hoffe es hilft!

Gustavo Garcia
quelle