401 réponse pour la demande CORS dans IIS avec L'authentification Windows activée
J'essaie d'activer le support CORS dans mon projet WebAPI, et si j'active L'authentification anonyme, tout fonctionne bien, mais avec L'authentification anonyme Windows Auth + désactivée, la demande d'OPTIONS envoyée renvoie toujours une réponse 401 non autorisée. Le site qui le demande est sur le domaine devrait donc être en mesure de faire l'appel, est - il possible de contourner le problème sans désactiver L'authentification Windows?
10 réponses
Vous pouvez autoriser uniquement les options verbe pour les utilisateurs anonymes.
<system.web>
<authentication mode="Windows" />
<authorization>
<allow verbs="OPTIONS" users="*"/>
<deny users="?" />
</authorization>
</system.web>
Selon les spécifications du W3C, le navigateur exclut les informations d'identification de L'utilisateur du contrôle préalable CORS: https://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request
Plusieurs années plus tard, mais grâce à la réponse de @dariusriggins et @lex-li, j'ai réussi à ajouter le code suivant à mon 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();
}
}
Le httpOrigin est en fait recherché dans une liste d'hôtes autorisés mais cela ne fait que compliquer les choses. Cela signifie que toutes les autres demandes sont validées mais les options retourne juste.
Merci pour cette question, j'aurais été perdu sans elle!
De MS:
Si vous désactivez l'authentification anonyme, c'est par conception QU'IIS renverrait un 401 à n'importe quelle requête. S'ils ont activé l'authentification Windows, la réponse 401 dans ce cas aurait un en-tête WWW-Authenticate pour permettre au client de démarrer une liaison d'authentification. La question devient alors si le client que le client utilise peut faire l'authentification Windows ou non.
Enfin, il semble qu'il pourrait y avoir une question sous-jacente à savoir si c'est possible ou ne pas configurer une URL de telle sorte qu'un accès anonyme soit autorisé pour un verbe (OPTIONS, dans ce cas), mais nécessite une authentification Windows pour les autres verbes. IIS ne prend pas en charge cela via une configuration simple. Il peut être possible d'obtenir ce comportement en activant L'authentification anonyme et Windows, en définissant des ACL sur le contenu qui refuse l'accès à l'utilisateur anonyme, puis en configurant le mappage du gestionnaire pour l'URL en question afin qu'il ne vérifie pas l'existence du fichier associé à L'URL. Mais il faudrait jouer avec pour confirmer cela.
Le moyen le plus simple de résoudre ce problème est de créer une règle de réécriture avec la condition request_method = ^OPTIONS$. Ensuite, définissez l'action comme une réponse personnalisée, définissez-la sur 200 OK. Ensuite, toutes les demandes d'options répondront avec 200 au lieu de 401. Cela corrigera le problème CORS.
Bien sûr, vous devez toujours vous assurer que vous avez les en-têtes de requête cross origin corrects.
Cela empêchera les demandes d'options (qui n'ont pas d'informations d'identification) de répondre avec 401 lorsque l'authentification intégrée est permettre.
J'ai rencontré le même problème aujourd'hui en raison d'un bug dans IE 10 et 11, j'utilise ServiceStack au lieu de WebApi, mais l'approche peut également fonctionner pour vous.
- activation de L'authentification Windows intégrée et anonyme sur le Site Web IIS.
- avoir une série de filtres sur le Pipeline ServiceStack,
- pour gérer cors et options request, sur Options request, j'Ajoute les en-têtes nécessaires et termine la requête,
- Filtre pour vérifier includng HttpRequest est Authentifié?,
- filtre etc,
Après avoir traversé tous les filtres, il exécute le service.
Dans mon AppHost,
appHost.Plugins.Add(new CorsFeature());
appHost.RequestFilters.Add(AuthenticateFilter.Authenticate);
J'ai modifié le CorsFeature pour gérer les OptionsRequest en plus d'ajouter des en-têtes, authentifier le filtre pour vérifier les requêtes authentifiées!
La réponse acceptée est correcte mais je dépannais une api rest avec une configuration "node with iisnode and npm cors module" pendant un certain temps et je n'étais pas à l'aise avec l'activation de l'authentification anonyme pour tous les utilisateurs. Puisque c'est une application de noeud le système.balise web ne fait pas beaucoup. Je me suis retrouvé avec l'ajout suivant sur le web.configuration:
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
<authorization>
<add accessType="Allow" verbs="OPTIONS" users="?" />
<add accessType="Deny" verbs="GET, PUT, POST, DELETE" users="?" />
</authorization>
</security>
</system.webServer>
J'utilise L'API Web et OWIN et j'ai essayé toutes les solutions suggérées mais la seule chose qui a fonctionné était la suivante
//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);
Vous devez insérer ce code quelque part dans l'une de vos classes de démarrage OWIN.
Il est important d'appeler app.UseStageMarker(PipelineStage.Authenticate)
car sinon la vérification en amont a échoué.
Plus d'infos pour UseStageMarker - > https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline
Il est également important que vous ayez besoin pour définir explicitement les en-têtes autorisés. Il échouera si vous utilisez *
comme espace réservé.
Peut-être que ça aide quelqu'un.
Ce qui a fonctionné pour moi (lorsque vous travaillez avec AngularJS ou JQuery) est d'ajouter withCredentials: true à chaque requête sur le client:
$http.get("http://localhost:88/api/tests", {withCredentials :true})
Et en activant CORS sur le serveur, cela a été fait avec Microsoft.Owin.Cors de nuget et l'ajouter au démarrage comme ci-dessous:
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
Références:
- CORS sur le serveur (voir étape 11): http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
- CORS sur le client: http://brockallen.com/2012/12/15/cors-and-windows-authentication/
Activation de SupportCredentials sur EnableCorsAttribute dans WebApiConfig.cs a fait l'affaire pour moi:
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
Assurez-vous d'envoyer des informations d'identification lors de l'appel à partir de javascript ({withCredentials :true}
)
Je comprends que c'est une vieille question avec plusieurs solutions possibles (ainsi que plus de questions), mais au cas où quelqu'un d'autre rencontrerait cela, IIS cors 1.0 est disponible à partir du 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
Vous pouvez le télécharger via IIS Windows Platform Installer (WPI). Cela devrait résoudre beaucoup de vos CORS problèmes d'authentification. Amusez-vous bien!