Activer l’authentification par jeton CORS pour Web Api 2 et OWIN

J’ai un projet Web ASP.NET MVC 5 (localhost: 81) qui appelle les fonctions de mon projet WebApi 2 (localhost: 82) à l’aide de Knockoutjs, pour établir la communication entre les deux projets que j’active CORS. Tout fonctionne jusqu’à présent, jusqu’à ce que j’essaye d’implémenter l’authentification par jeton OWIN sur WebApi.

Pour utiliser le noeud final / token sur WebApi, je dois également activer CORS sur le noeud final, mais après des heures d’essai et de recherche de solutions, il fonctionne toujours et l’application / jeton a toujours pour résultat:

XMLHttpRequest cannot load http://localhost:82/token. No 'Access-Control-Allow-Origin' header is present on the requested resource. public void Configuration(IAppBuilder app) { app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); TokenConfig.ConfigureOAuth(app); ... } 

TokenConfig

 public static void ConfigureOAuth(IAppBuilder app) { app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext(AppUserManager.Create); OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true, TokenEndpointPath = new PathSsortingng("/token"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), Provider = new SimpleAuthorizationServerProvider() }; app.UseOAuthAuthorizationServer(OAuthServerOptions); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } 

AutorisationFournisseur

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); var appUserManager = context.OwinContext.GetUserManager(); IdentityUser user = await appUserManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ... claims } 

IdentityConfig

 public static AppUserManager Create(IdentityFactoryOptions options, IOwinContext context) { // Tried to enable it again without success. //context.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"}); var manager = new AppUserManager(new UserStore(context.Get())); ... var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } 

MODIFIER:

1. Il est important de noter que l’ouverture directe du noeud final (localhost: 82 / token) fonctionne.

2. L’appel de l’API (localhost: 82 / api / ..) à partir du projet Web fonctionne également. Par conséquent, CORS est activé pour WebApi.

Je sais que votre problème a été résolu dans les commentaires, mais j’estime qu’il est important de comprendre sa cause et comment résoudre toute cette catégorie de problèmes.

En regardant votre code, vous pouvez voir que vous définissez l’en Access-Control-Allow-Origin tête Access-Control-Allow-Origin plusieurs fois pour le noeud final Token:

 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

Et à l’intérieur de la méthode GrantResourceOwnerCredentials :

 context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

Cela, en regardant les spécifications de la SCRO , est en soi un problème pour les raisons suivantes:

Si la réponse inclut zéro ou plus d’une valeur d’en-tête Access-Control-Allow-Origin, renvoyez fail et mettez fin à cet algorithme.

Dans votre scénario, la structure définit cet en-tête deux fois et comprend que la procédure CORS doit être implémentée entraîne la suppression de l’en-tête dans certaines circonstances (éventuellement liée au client).

Ceci est également confirmé par la réponse à la question suivante: Duplicate Access-Control-Allow-Origin: * provoque une erreur COR?

Pour cette raison, le déplacement de l’appel vers app.UseCors après l’appel de ConfigureOAuth permet de définir votre en-tête app.UseCors une seule fois (car le pipeline owin est interrompu au niveau du middleware OAuth et n’atteint jamais le middleware Microsoft CORS du terminal Token ) et Votre appel à Ajax fonctionne.

Pour une meilleure solution globale, vous pouvez essayer de remettre app.UseCors avant l’appel du middleware OAuth et supprimer la deuxième insertion de Access-Control-Allow-Origin dans GrantResourceOwnerCredentials .

Suivez les étapes ci-dessous pour que votre API fonctionne:

  1. Supprimez tout code tel que config.EnableCors(), [EnableCors(header:"*"....)] de votre API.
  2. Allez dans startup.cs et ajoutez la ligne ci-dessous

     app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

avant

  ConfigureAuth(app); 

Vous devrez également installer le package Microsoft.owin.cors pour utiliser cette fonctionnalité.