web-dev-qa-db-fra.com

Comment faire l'authentification CORS dans Web API 2?

Le scénario est simple, je dois me connecter depuis un autre serveur (différent du serveur API) pour récupérer le jeton d'accès.

J'ai installé le paquet Microsoft.Owin.Cors Sur le serveur API. Dans le fichier Startup.Auth.cs, Sous public void ConfigureAuth(IAppBuilder app), j’ai ajouté dans

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

Dans WebApiConfig.cs, Sous public static void Register(HttpConfiguration config), j'ai ajouté dans ces lignes:

// Cors
var cors = new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS");
config.EnableCors(cors);

Que devrais-je changer?

71
Blaise

Regardez ce que j'ai trouvé!

Ajoutez des en-têtes personnalisés à l'intérieur de <system.webServer>.

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
  </customHeaders>
</httpProtocol>

Ensuite, je peux faire l'authentification CORS.

78
Blaise

J'ai eu beaucoup d'essais et d'erreurs pour le configurer pour le client Web basé sur AngularJS.
Pour moi, les approches ci-dessous fonctionnent avec ASP.NET WebApi 2.2 et le service OAuth.

  1. Installez le paquet de nuget Microsoft.AspNet.WebApi.Cors.
  2. Installez le paquet de nuget Microsoft.Owin.Cors.
  3. Ajoutez config.EnableCors(new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS, PUT, DELETE")); au-dessus de WebApiConfig.Register(config); ligne dans le fichier Startup.cs .
  4. Ajoutez app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); au fichier Startup.Auth.cs . Cela doit être fait avant d'appeler IAppBuilder.UseWebApi
  5. Supprimez tous les paramètres XML que Blaise a fait.

J'ai trouvé beaucoup de variations et de combinaisons d'installation ici: stackoverflow ou articles de blog . Donc, l'approche de Blaise peut ne pas être fausse. C'est juste un autre paramètre, je pense.

47
Youngjae

Après de nombreuses heures de recherche et de recherche sur de nombreuses solutions différentes à ce problème, j’ai réussi à le faire fonctionner comme indiqué ci-dessous.

Il y a plusieurs raisons à cela. CORS est probablement activé au mauvais endroit ou est activé deux fois ou pas du tout.

Si vous utilisez l'API Web et le noeud final Owin Token, vous devez supprimer toutes les références à CORS dans votre méthode d'API Web et ajouter la méthode owin appropriée, car les api cors Web ne fonctionneront pas avec le noeud final Token, tandis qu'Owin cors fonctionnera pour les deux sites Web. Points finaux d’authentification API et Token, commençons donc:

  1. Assurez-vous que le package Owin Cors est installé. Supprimez toutes les lignes dont vous disposez, par exemple ,.config.EnableCors (); à partir de votre fichier WebAPIconfig.cs

  2. Accédez à votre fichier startup.cs et assurez-vous d'exécuter Owin Cors avant toute autre configuration.

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

  3. Si vos problèmes persistent, accédez à: Startup.Auth.cs et assurez-vous que votre méthode ConfigureAuth contient les éléments suivants (vous ne devriez pas en avoir besoin si votre fichier startup.cs est correct)

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

30
Piotr Stulinski

web.config

<appSettings>
  <add key="cors:Origins" value="*" />
  <add key="cors:Headers" value="*" />
  <add key="cors:Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
</appSettings>

Startup.cs

var appSettings = WebConfigurationManager.AppSettings;

// If CORS settings are present in Web.config
if (!string.IsNullOrWhiteSpace(appSettings["cors:Origins"]))
{
    // Load CORS settings from Web.config
    var corsPolicy = new EnableCorsAttribute(
        appSettings["cors:Origins"],
        appSettings["cors:Headers"],
        appSettings["cors:Methods"]);

    // Enable CORS for ASP.NET Identity
    app.UseCors(new CorsOptions
    {
        PolicyProvider = new CorsPolicyProvider
        {
            PolicyResolver = request =>
                request.Path.Value == "/token" ?
                corsPolicy.GetCorsPolicyAsync(null, CancellationToken.None) :
                Task.FromResult<CorsPolicy>(null)
        }
    });

    // Enable CORS for Web API
    config.EnableCors(corsPolicy);
}

Remarque : app.UserCors(...) doit être appelé avant la configuration de l'identité ASP.NET.

Source: Kit de démarrage pour application Web ASP.NET (API Web ASP.NET, Identity, SignalR)

21

Pour élaborer la réponse de Youngjae, il existe un excellent didacticiel sur la configuration d’OWIN avec Web API et sur l’activation de CORS dans le processus à l’adresse http://bitoftech.net/2014/06/01/token-based-authentication-asp- net-web-api-2-owin-asp-net-identity /

Vous voudrez ajouter le package NuGet pour CORS avec la commande:
Install-Package Microsoft.Owin.Cors -Version 2.1.0

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

à votre méthode de configuration dans Startup.cs afin qu'il ressemble à quelque chose comme:

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

La réponse pour moi a été trouvée à

demande Web Api 2 Preflight CORS pour un jeton porteur

Plus précisément, la demande/Token utilisant une implémentation de OAuthAuthorizationServerProvider.GrantResourceOwnerCredentials ajoutait à nouveau l'en-tête. Ajoutez les éléments OWIN CORS avant toute autre configuration OWIN et supprimez l'en-tête de GrantResourceOwnerCredentials, conformément à ce lien, et le tour est joué. Bonne chance.

9
Dale Holborow

Je veux juste partager mon expérience. J'ai passé la moitié de la journée à me cogner la tête et à essayer de la faire fonctionner. J'ai lu de nombreux articles et SO questions et finalement j'ai compris ce qui n'allait pas.

La ligne

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

n'était pas le premier de la méthode Startup class Configuration. Quand je l'ai déplacé au sommet, tout a commencé à fonctionner comme par magie.

Et aucun en-tête personnalisé dans web.config Ou config.EnableCors(corsPolicy); ou quoi que ce soit d'autre n'était nécessaire.

J'espère que cela aidera quelqu'un à gagner du temps.

9
Andrew

Vous pouvez trouver ici les différentes manières d'activer CORS à différents niveaux: http://www.asp.net/web-api/overview/security/enabling-cross-cross-Origin-requests-in-web- api

Quoi qu'il en soit, j'ai eu le même problème et, en ajoutant les en-têtes de différentes manières, la solution complète n'a pas été trouvée.

J'ai découvert que IIS utilise des gestionnaires qui remplacent la configuration de votre application Web CORS si vous ne spécifiez pas le contraire.

Dans mon cas, j'ai également dû supprimer l'utilisation des gestionnaires IIS) en ajoutant la configuration suivante au niveau du fichier Web.config principal de mon application:

<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

Sachez que cette configuration peut être définie par défaut lorsque vous créez un nouveau projet, en fonction du type, mais si vous partez de zéro, vous devrez probablement ajouter cette configuration.

4
Seba Cervantes

L'ajout d'en-têtes de clients peut vous donner moins de liberté pour personnaliser vos besoins en matière de sécurité. Il ouvre toutes les autres parties de l'API au monde. Le code suivant ne le fait que pour "token", et le contrôleur, une autre partie de api, doit être créé via une annotation EableCors.

public void ConfigureAuth(IAppBuilder app)
{
    //other stuff
    app.Use(async (context, next) =>
    {
        IOwinRequest req = context.Request;
        IOwinResponse res = context.Response;
        if (req.Path.StartsWithSegments(new PathString("/Token")))
        {
            var Origin = req.Headers.Get("Origin");
            if (!string.IsNullOrEmpty(Origin))
            {
                res.Headers.Set("Access-Control-Allow-Origin", Origin);
            }
            if (req.Method == "OPTIONS")
            {
                res.StatusCode = 200;
                res.Headers.AppendCommaSeparatedValues("Access-Control-    Allow-Methods", "GET", "POST");
                res.Headers.AppendCommaSeparatedValues("Access-Control-    Allow-Headers", "authorization", "content-type");
                return;
            }
        }
        await next();
    });
    //other stuff
}

Pour activer Cors, suivez les instructions ici .

2
Tim Hong

Lors de l'utilisation du middleware OWIN pour gérer CORS, il n'est pas nécessaire d'ajouter des en-têtes sur le fichier WebAPIConfig ou le fichier web.config. Oui, l'ajout des en-têtes du fichier web.config fonctionne lorsque vous souhaitez un accès public, mais si vous devez limiter l'accès sur la base d'une liste blanche (domaines), autorisez All l’accès n’est plus ce que vous voudriez faire.

Avec OWINS, nous pouvons gérer cela en implémentant ce gestionnaire:

OAuthAuthorizationServerProvider.MatchEndpoint

Avec ce gestionnaire, nous pouvons détecter la méthode de requête (OPTIONS, POST ...) et si la requête doit être traitée comme un noeud final Authorize ou Token. C'est la zone où la logique peut être ajoutée pour vérifier l'en-tête Origin (demande) et valider si ce domaine doit être autorisé en ajoutant l'en-tête de réponse Access-Control-Allow-Origin.

string Origin = context.Request.Headers.Get("Origin");
var found = IsDomainAllowed(Origin);
 if (found){
      context.Response.Headers.Add("Access-Control-Allow-Origin",
                             new string[] { Origin });
 }      

Pour plus d'informations à ce sujet, consultez le lien suivant: http://www.ozkary.com/2016/04/web-api-owin-cors-handling-no-access.html

1
ozkary

Soluction complète. Vous avez juste besoin de changer certains fichiers, ça marche pour moi.

Global.ascx

public class WebApiApplication : System.Web.HttpApplication {
    protected void Application_Start()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    } }

WebApiConfig.cs

Toute la requête a appeler ce code.

public static class WebApiConfig {
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
        AddRoutes(config);
    }

    private static void AddRoutes(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "Default",
            routeTemplate: "api/{controller}/"
        );
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute(
            origins: "*", 
            headers: "*", 
            methods: "*");
        config.EnableCors(cors);
    } }

Certains contrôleurs

Rien à changer.

Web.config

Vous devez ajouter des gestionnaires dans votre web.config

<configuration> 
  <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>   
  </system.webServer> 
</configuration>
0
Jonas Ribeiro