Risposta 401 per richiesta CORS in IIS con autenticazione di Windows abilitata

Sto cercando di abilitare il supporto CORS nel mio progetto WebAPI e, se abilito l’autenticazione anonima, tutto funziona correttamente, ma con autenticazione anonima disabilitata di Windows Auth, la richiesta OPTIONS inviata restituisce sempre una risposta non autorizzata 401. Il sito che lo richiede è DOMAIN quindi dovrebbe essere in grado di effettuare la chiamata, c’è un modo per aggirare il problema senza disabilitare l’autenticazione di Windows?

Puoi consentire solo il verbo OPTIONS per gli utenti anonimi.

       

Secondo le specifiche W3C, il browser esclude le credenziali dell’utente dal preflight CORS: https://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request

Diversi anni dopo, ma attraverso la risposta di @dariusriggins e @ lex-li sono riuscito ad aggiungere il seguente codice al mio Global.asax:

  public void Application_BeginRequest(object sender, EventArgs e) { string httpOrigin = Request.Params["HTTP_ORIGIN"]; if (httpOrigin == null) httpOrigin = "*"; HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true"); if (Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.StatusCode = 200; var httpApplication = sender as HttpApplication; httpApplication.CompleteRequest(); } } 

l’httpOrigin è in realtà cercato in una lista di host consentiti ma solo cose complicate. Ciò significa che tutte le altre richieste vengono convalidate ma le opzioni restituiscono semplicemente.

Grazie per questa domanda, mi sarei perso senza di essa!

Dalla SM:

Se si disabilita l’autenticazione anonima, è in base alla progettazione che IIS restituirà un 401 a qualsiasi richiesta. Se hanno abilitato l’autenticazione di Windows, la risposta 401 in quel caso avrebbe un’intestazione WWW-Authenticate per consentire al client di avviare un handshake di autenticazione. La domanda diventa quindi se il client che il cliente sta usando può fare l’autenticazione di Windows o meno.

Infine, sembra che potrebbe esserci una domanda di fondo sulla possibilità o meno di configurare un URL in modo che l’accesso anonimo sia consentito per un verbo (OPZIONI, in questo caso), ma richiede l’autenticazione di Windows per altri verbi. IIS non supporta questo tramite una semplice configurazione. Potrebbe essere ansible ottenere questo comportamento abilitando l’autenticazione anonima e Windows, impostando gli ACL sul contenuto che negano l’accesso all’utente anonimo e quindi configurando il mapping del gestore per l’URL in questione in modo che non verifichi l’esistenza del file associato all’URL. Ma ci vorrebbe un po ‘di gioco per confermare questo.

Il modo più semplice per risolvere questo problema è creare una regola di riscrittura con la condizione request_method = ^ OPTIONS $. Quindi impostare l’azione come risposta personalizzata, impostarla su 200 OK. Quindi tutte le richieste di opzioni risponderanno con 200 anziché 401. Questo risolverà il problema CORS.

Naturalmente è ancora necessario accertarsi di avere le intestazioni delle richieste di origine incrociata corrette.

Ciò interromperà le richieste di opzioni (che non hanno credenziali) che rispondono con 401 quando è abilitata l’autenticazione integrata.

Ho incontrato lo stesso problema oggi a causa di un bug in IE 10 e 11 , sto usando ServiceStack invece di WebApi, ma l’approccio può funzionare anche per te.

  1. Abilitato l’autenticazione integrata e anonima di Windows sul sito Web IIS.
  2. Hanno una serie di filtri sulla pipeline ServiceStack,
    • Per la gestione delle richieste Cors e OPTIONS, su richiesta Opzioni, aggiungo le intestazioni necessarie e termino la richiesta,
    • Filtro per il controllo includng HttpRequest è autenticato ?,
    • filtro etc,

Dopo aver attraversato tutti i filtri, esegue il servizio.

CorsFeature.cs

AuthenticateFilter

Nel mio AppHost,

 appHost.Plugins.Add(new CorsFeature()); appHost.RequestFilters.Add(AuthenticateFilter.Authenticate); 

Ho modificato il CorsFeature per gestire OptionsRequest oltre ad aggiungere intestazioni, Authenticate Filter per verificare le richieste autenticate!

La risposta accettata è corretta, tuttavia stavo risolvendo un problema con un “nodo con iisnode e il modulo del modulo npm cors” per un po ‘e non mi sentivo a mio agio con l’abilitazione dell’autenticazione anonima per tutti gli utenti. Dal momento che è un’applicazione nodo, il tag system.web non fa molto. Ho finito con la seguente aggiunta al web.config:

              

Sto usando Web API e OWIN e ho provato ogni soluzione suggerita, ma l’unica cosa che ha funzionato è stata la seguente

 //use it in your startup class app.Use((context, next) => { if (context.Request.Headers.Any(k => k.Key.Contains("Origin")) && context.Request.Method == "OPTIONS") { context.Response.StatusCode = 200; context.Response.Headers.Add("Access-Control-Allow-Origin", new string[1] { "ALLOWED_ORIGIN" }); context.Response.Headers.Add("Access-Control-Allow-Headers", new string[4] { "Origin", "X-Requested-With", "Content-Type", "Accept" }); context.Response.Headers.Add("Access-Control-Allow-Methods", new string[5] { "GET", "POST", "PUT", "DELETE", "OPTIONS" }); context.Response.Headers.Add("Access-Control-Allow-Credentials", new string[1] { "true" }); return context.Response.WriteAsync(""); } return next.Invoke(); }); //this is important! Without it, it didn't work (probably because the middleware was too late) app.UseStageMarker(PipelineStage.Authenticate); 

è necessario inserire questo codice da qualche parte in una delle tue classi di avvio OWIN. È importante chiamare app.UseStageMarker(PipelineStage.Authenticate) perché altrimenti il ​​controllo di preflight non è riuscito. Ulteriori informazioni su UseStageMarker -> https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

È anche importante che sia necessario definire esplicitamente le intestazioni consentite. Fallirà se usi * come segnaposto.

Forse aiuta qualcuno.

Ciò che ha funzionato per me (quando si lavora con AngularJS o JQuery) è aggiungere withCredentials: true a ogni richiesta sul client:

 $http.get("http://localhost:88/api/tests", {withCredentials :true}) 

E abilitando CORS sul server, questo è stato fatto con Microsoft.Owin.Cors da nuget e aggiungendolo all’avvio come di seguito:

 public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); ConfigureOAuth(app); WebApiConfig.Register(config); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); } 

Riferimenti:

Abilitare SupportCredentials su EnableCorsAttribute in WebApiConfig.cs ha fatto il trucco per me:

 public static void Register(HttpConfiguration config) { //enable cors request just from localhost:15136 var cors = new EnableCorsAttribute("http://localhost:15136", "*", "*"); cors.SupportsCredentials = true; config.EnableCors(cors); //other stuff } 

https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

Assicurati di inviare le credenziali quando chiami da javascript ( {withCredentials :true} )

Capisco che questa è una vecchia domanda con diverse possibili soluzioni (oltre a più domande), ma nel caso che qualcun altro si imbatta in questo, IIS CORS 1.0 è disponibile a partire dal 17 novembre:

https://blogs.iis.net/iisteam/introducing-iis-cors-1-0

https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference

È ansible scaricarlo tramite IIS Windows Platform Installer (WPI). Questo dovrebbe risolvere molti dei tuoi problemi di autenticazione CORS. Godere!