31 votes

Authentification Dotnet Core 2.0, plusieurs schémas d'identité, cookies et jwt

Dotnet core 1.1 asp, j'ai été en mesure de configurer et d'utiliser l'identité middleware suivie par jwt de l'intergiciel en procédant de la manière suivante:

  app.UseIdentity();
  app.UseJwtBearerAuthentication(new JwtBearerOptions() {});

Cela a changé en ce que nous mettons en œuvre le middleware avec:

   app.UseAuthentication();

Configuration des paramètres se fait via le ConfigureServices la section de Démarrage.cs.

Il y a quelques références à l'utilisation de l'autorisation du schéma de la migration de la documentation:

https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x#authentication-middleware-and-services

Dans les projets 2.0, l'authentification est configuré par l'intermédiaire des services. Chaque schéma d'authentification est enregistré dans l'ConfigureServices méthode de De démarrage.cs. Le UseIdentity méthode est remplacé par UseAuthentication.

En outre, il est une référence à:

Le Réglage Par Défaut De Schémas D'Authentification

En 1.x, le AutomaticAuthenticate et AutomaticChallenge propriétés étaient destinés à être installés sur un seul schéma d'authentification. Il n'y a pas de bonne façon de respecter cela.

En 2.0, ces deux propriétés ont été retiré que des drapeaux sur l'individu AuthenticationOptions instance et déplacé dans la base de AuthenticationOptions classe. Les propriétés peut être configuré dans le AddAuthentication appel de méthode à l'intérieur de la ConfigureServices méthode de Démarrage.cs:

Vous pouvez également utiliser une version surchargée de la AddAuthentication méthode pour définir plus d'une propriété. Dans la suite de surcharge méthode d'exemple, le schéma par défaut est définie à CookieAuthenticationDefaults.AuthenticationScheme. L'authentification le schéma peut également être spécifié dans votre propre [Autoriser] les attributs ou les politiques d'autorisation.

Est-il encore possible en dotnet core 2.0 pour l'utilisation de plusieurs schémas d'authentification? Je n'arrive pas à la politique de respect de la JWT de configuration ("Porteur" du schéma), et seule Identité travaille à présent avec les deux configuré. Je ne peux pas trouver tous les échantillons de plusieurs schémas d'authentification.

Edit:

J'ai relu la documentation, et maintenant comprendre que l':

app.UseAuthentication()

ajoute l'authentification automatique à l'encontre d'un schéma par défaut. L'identité configure les schémas par défaut pour vous.

J'ai contourné le problème avec ce qui semble être un hack de travail contre la nouvelle api de la manière suivante au Démarrage.cs Configurer:

    app.UseAuthentication();
    app.Use(async (context, next) =>
    {
        if (!context.User.Identity.IsAuthenticated)
        {
            var result = await context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
            if (result?.Principal != null)
            {
                context.User = result.Principal;
            }
        }

        await next.Invoke();
    });

Est-ce la bonne façon de le faire, ou devrais-je utiliser le cadre, DI et interfaces des implémentations personnalisées de IAuthenticationSchemeProvider?

Modifier - pour de Plus amples détails de la mise en œuvre et où le trouver.

Le JWT Config peut être trouvé ici, et je suis en utilisant des stratégies afin de définir l'autorisation, qui comprennent les acceptée auth du schéma:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Management/Startup.cs

Personnalisé middleware est encore mis en œuvre. Le contrôleur de Auth est ici:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/AuthController.cs

Il utilise l'API de Clés générées par l'application d'obtenir un accès en lecture seule aux données. Vous pouvez trouver à la mise en œuvre d'un contrôleur en utilisant la politique de ici:

https://github.com/Arragro/ArragroCMS/blob/master/src/ArragroCMS.Web.Management/ApiControllers/SitemapController.cs

Modifier la DB de la chaîne de Connexion pour pointer vers votre Serveur SQL server et exécutez l'application. Il migre la DB automatiquement et configure un utilisateur admin (support@arragro.com - ArragroPassword1!). Ensuite, allez à l'onglet Paramètres dans la barre de menu et cliquez sur "Configurer le JWT ReadOnly Clé API Paramètres" pour obtenir une clé. Dans le facteur, obtenir un jwt jeton par la configuration d'un nouvel onglet et le mettre à la POSTE à l'adresse suivante:

http://localhost:5000/api/auth/readonly-token

Approvisionnement les en-têtes: Content-Type: application/json

L'approvisionnement de l'organisme:

{
    "apiKey": "the api token from the previous step"
}

Copiez le jeton dans la réponse, et puis utilisez la commande suivante en facteur:

http://localhost:5000/api/sitemap/flat

Authorization: "bearer - The token you received in the previous request"

Il travaillera inititally en raison de la coutume de middleware. Commentez le code mentionné ci-dessus et essayez de nouveau et vous recevrez un 401.

Edit@DonnyTian la réponse ci-dessous couvre ma solution dans ses commentaires. Le problème que j'ai est le réglage par défaut de la politique sur UseMvc, mais ne pas fournir le schéma:

    services.AddMvc(config =>
    {
        var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(defaultPolicy));
        config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        config.Filters.Add(new ValidateModelAttribute());
    });

En suivant les conseils, cela fonctionne sans personnalisé middleware.

28voto

DonnyTian Points 349

Asp.Net Core 2.0 certainement en charge plusieurs systèmes d'authentification. Plutôt que d'un piratage avec authentifier middleware, vous pouvez essayer de spécifier le schéma en Authorize d'attribut:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

J'ai donné un essai et il a bien fonctionné. En supposant que vous avez ajoutées à la fois l'Identité et JWT comme ci-dessous:

services.AddIdentity<ApplicationUser, ApplicationRole>()
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

Depuis AddIdentity() déjà définir l'authentification par cookie le schéma par défaut, nous devons spécifier le schéma en Authorize attribut de contrôleurs. Pour l'instant, je n'ai aucune idée de comment faire pour remplacer le schéma par défaut définie par l' AddIdentity(), ou peut-être que nous ferions mieux de ne pas le faire.

Un travail autour de est de composer une nouvelle classe (vous pouvez l'appeler JwtAuthorize) qui découle de l' Authorize et ont au Porteur que le schéma par défaut, de sorte que vous n'avez pas à spécifier à chaque fois.

Mise à JOUR

Trouvé le moyen de remplacer l'Identité schéma d'authentification par défaut!

Au lieu de la ligne ci-dessous:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

Utiliser en dessous de la surcharge de définir le schéma par défaut:

services.AddAuthentication(option =>
                {
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>....

Mise à JOUR 2 Comme mentionné dans les commentaires, vous pouvez vous permettre à la fois de l'Identité et de JWT auth par se joindre à eux. [Authorize(AuthenticationSchemes = "Identity.Application" + "," + JwtBearerDefaults.AuthenticationScheme)]

16voto

MartinH Points 862

J'ai utilisé cette question pour la résolution de mon (similaire) problème de la combinaison de l'Identité et de la Porteur de l'authentification dans un .Net Core 2.0 de l'application web. Important à noter est que vous devez ajouter new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme pour le morceau de code suivant:

services.AddMvc(config =>
    {
        var defaultPolicy = new AuthorizationPolicyBuilder(new[] { JwtBearerDefaults.AuthenticationScheme, IdentityConstants.ApplicationScheme })
                         .RequireAuthenticatedUser()
                         .Build();
        config.Filters.Add(new AuthorizeFilter(defaultPolicy));
        config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        config.Filters.Add(new ValidateModelAttribute());
    });

ET

Ajouter l'option d'authentification par défaut:

services.AddAuthentication(option =>
                {
                    option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options =>....

Dans ma première solution basée sur cette question, je n'ai pas d'avis que les deux changements dans mon code ont été nécessaires. J'espère que je peux sauver quelqu'un les heures que j'ai perdu :)

1voto

John Points 21

Basé sur ce que Kevin Rich dit ici http://www.whoiskevinrich.com/configuring-asp-net-core-2-0-authentication

J'ai pu définir jwt comme méthode d'authentification par défaut:

         services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            sharedOptions.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
        })
 

J'ai testé cela et j'ai pu supprimer (AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme) de l'attribut authorize mentionné dans le post de donnytian.

0voto

Guerrilla Points 2609

Sean Wildermuth a publié un blog sur l'activation des cookies et des jwt: https://wildermuth.com/2017/08/19/Two-AuthorizationSchemes-in-ASP-NET-Core-2

Il l'enchaîne comme ceci:

 services.AddAuthentication()
  .AddCookie(cfg => cfg.SlidingExpiration = true)
  .AddJwtBearer(cfg =>
  {
    cfg.RequireHttpsMetadata = false;
    cfg.SaveToken = true;

    cfg.TokenValidationParameters = new TokenValidationParameters()
    {
      ValidIssuer = Configuration["Tokens:Issuer"],
      ValidAudience = Configuration["Tokens:Issuer"],
      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
    };

  });
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X