2013-07-05 11 views
13

Mam problem z CORS podczas samodzielnego hostowania SignalR z OWIN, co ma miejsce tylko wtedy, gdy próbuję włączyć uwierzytelnianie.Połączenia międzydomenowe SignalR z samodzielnym hostowaniem i uwierzytelnianiem

Błąd pojawia się w przeglądarce internetowej jest:

XMLHttpRequest nie może załadować http://.../signalr/negotiate?[snip] Origin ... nie jest dozwolone przez Access-Control-Allow-Origin

Dzieje się tak tylko wtedy, gdy I włączyć uwierzytelnianie w moim własnym hostingiem za pomocą podejścia w this answer:

public void Configuration(IAppBuilder app) 
{ 
    var listener = (HttpListener)app.Properties[typeof(HttpListener).FullName]; 
    listener.AuthenticationSchemes = AuthenticationSchemes.Ntlm; 

    app.MapHubs(new HubConfiguration { EnableCrossDomain = true }); 
} 

Gdybym zakomentuj AuthenticationSchemes linia wtedy działa CORS (i sprawdziłem wszystko w these instructions). Ten sam problem występuje, jeśli korzystam z innych schematów uwierzytelniania niż NTLM.

Korzystanie Skrzypek, aby sprawdzić, co się dzieje, bez uwierzytelniania włączona widzę niezbędne nagłówki Cors wracając z serwera:

kontroli dostępu-ce-Poświadczenia: true
Access-Sterowanie Pozwól-Origin: [mój serwer]

Jednak po włączeniu uwierzytelniania otrzymuję odpowiedź 401, której brakuje tych nagłówków. Wszystkie żądania mają wymagany nagłówek Origin.

Po zbadaniu SignalR source code wygląda na to, że nagłówki są ustawiane, ale prawdopodobnie przy włączonej autoryzacji HttpListener wysyła początkową odpowiedź 401 bez uderzania w ten kod.

Więc myślę, że moje pytanie brzmi: w jaki sposób uzyskać HttpListener do włączenia nagłówka Access-Control-Allow-Origin w negocjacjach protokołów uwierzytelniania?

+0

Czy zdarzyło Ci się to jeszcze bardziej? Cierpię na ten sam problem ... –

Odpowiedz

4

Otrzymałem uwierzytelnienie NTLM do pracy z sygnaturą w domenie krzyżowej w trybie samoobsługi w OWIN, zezwalając preflightowi na dostęp anonimowy.

Należy utworzyć delegata w celu wybrania schematu uwierzytelniania, który wyszuka nagłówki żądań wstępnych, i zezwoli na to anonimowo. Wszystkie inne żądania będą korzystać z NTLM.

public void Configuration(IAppBuilder appBuilder) 
{ 
    var listener = (HttpListener)appBuilder.Properties[typeof(HttpListener).FullName]; 
    listener.AuthenticationSchemeSelectorDelegate += AuthenticationSchemeSelectorDelegate; 
} 

private AuthenticationSchemes AuthenticationSchemeSelectorDelegate(HttpListenerRequest httpRequest) 
{ 
    if (httpRequest.Headers.Get("Access-Control-Request-Method")!=null) 
     return AuthenticationSchemes.Anonymous; 
    else 
     return AuthenticationSchemes.Ntlm; 
} 
+0

Dzięki za sugestię!Wydaje się, że jest to obiecująca droga, ale moja przeglądarka nie wydaje żadnych żądań preflight, co oznacza, że ​​tak naprawdę nie pomaga. To zainspirowało mnie do znalezienia właściwości UnsafeConnectionNtlmAuthentication, która prawie osiąga coś podobnego (pierwsze żądanie dotyczy zasobu, który nie wymaga CORS, a kolejne żądania ponownie wykorzystują uwierzytelnianie od pierwszego). To jednak po jakimś czasie upada, ponieważ poświadczenia są buforowane dla połączenia TCP, a mój klient ewidentnie kończy otwieranie więcej niż jednego połączenia. To i tak włamanie. Będę próbować ... –

+0

Dziękuję bardzo! Rozszarpałam włosy, próbując zmusić to do pracy. –

3

Przypuszczam, że używasz Chrome, który bardzo unhelpfully mówi, że te nagłówki brakuje i że jest to problem, gdy rzeczywiście masz prawdopodobnie po prostu zapomniał ustawić withCredentials własność twoi XMLHttpRequest „s do true.

Jeśli używasz jQuery można to zrobić dla wszystkich żądań z:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) { 
    options.xhrFields = { withCredentials: true }; 
}); 

Trzeba także zrobić dobry uczynek z OPTIONS wniosków jak w drugiej odpowiedzi.

Powiązane problemy