0

Je tente de configurer un serveur d'identité 4 + API + scénario Web mais je ne parviens pas à obtenir l'authentification des utilisateurs dans l'API. Chaque composant utilise un projet distinct dans ma solution VS. Tous les projets sont sur Dotnetcore 2.0.IdentityServer4 sur .Net Core2 avec support - API ne validant pas le gestionnaire de règles auth/custom

Startup.cs Identity Server

services.AddIdentity<ApplicationUser, ApplicationRole>() 
       .AddEntityFrameworkStores<ApplicationDbContext>() 
       .AddDefaultTokenProviders(); 
services.AddCors(); 
services.AddIdentityServer(options => 
      { 
       options.Events.RaiseSuccessEvents = true; 
       options.Events.RaiseFailureEvents = true; 
       options.Events.RaiseErrorEvents = true; 
      }) 
      .AddInMemoryClients(Clients.Get()) 
      .AddInMemoryIdentityResources(Resources.GetIdentityResources()) 
      .AddInMemoryApiResources(Resources.GetApiResources()) 
      .AddDeveloperSigningCredential() 
.AddExtensionGrantValidator<Extensions.ExtensionGrantValidator>() 
      .AddExtensionGrantValidator<Extensions.NoSubjectExtensionGrantValidator>() 
.AddTestUsers(TestUsers.Users); 

TestUsers.Users

public class TestUsers 
    { 
     public static List<IdentityServer4.Test.TestUser> Users = new List<IdentityServer4.Test.TestUser> 
     { 
      new IdentityServer4.Test.TestUser{SubjectId = "818727", Username = "alice", Password = "alice", 
       Claims = 
       { 
        new Claim(JwtClaimTypes.Role, "UserEditor"), 
        new Claim(JwtClaimTypes.Name, "Alice Smith"), 
        new Claim(JwtClaimTypes.Email, "[email protected]"), 
       } 
      }, 
      new IdentityServer4.Test.TestUser{SubjectId = "88421113", Username = "bob", Password = "bob", 
       Claims = 
       { 
        new Claim(JwtClaimTypes.Role, "Root"), 
        new Claim(JwtClaimTypes.Role, "Admin"), 
        new Claim(JwtClaimTypes.Role, "UserEditor"), 
        new Claim(JwtClaimTypes.Name, "Bob Smith"), 
        new Claim(JwtClaimTypes.Email, "[email protected]") 
       } 
      } 
     }; 
    } 

Obtenir un jeton porteur indentityserver œuvres JWT via http://localhost:2266/connect/token et contient les informations pertinentes:

{ ... ... "rôle": [ "Root", "Admin", "UserEditor" ], "scope": [... ], ...}

Cependant, du côté de l'API, l'authentification n'est pas vérifiée correctement.

API Startup.cs

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDbContext... 
    ... 
    ... 

    services.AddMvcCore() 
    .AddAuthorization() 
    .AddJsonFormatters(); 

    services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) 
    .AddIdentityServerAuthentication(options => 
     { 
      options.Authority = "http://localhost:2266"; 
      options.RequireHttpsMetadata = false; 

      options.ApiSecret = "secret"; 
      options.ApiName = "MyApi"; 
     }); 

    services.AddCors(options => 
    { 
     // this defines a CORS policy called "default" 
     options.AddPolicy("default", policy => 
     { 
      policy.WithOrigins("http://localhost:44352") 
       .AllowAnyHeader() 
       .AllowAnyMethod(); 
     }); 
    }); 

    // custom policy attributes 
    services.AddAuthorization(options => 
    { 
     options.AddPolicy("Root", policy => policy.Requirements.Add(new Models.Policies.MyPolicyRequirement("Root"))); 
     options.AddPolicy("Admin", policy => policy.Requirements.Add(new Models.Policies.MyPolicyRequirement("Admin"))); 
     options.AddPolicy("UserEdit", policy => policy.Requirements.Add(new Models.Policies.MyPolicyRequirement("UserEdit"))); 
    }); 

    services.AddSingleton<IAuthorizationHandler, Models.Policies.MyPolicyHandler>(); 
    services.AddMvc(); 

    // add swagger 
    ... 
} 

La politique de validation Controller/Actions sont marqués avec l'attribut Autorisez, par exemple [Authorize (Politique = "Root")] Le code de la Le gestionnaire de règles est touché pendant le débogage.

public class MyPolicyHandler : AuthorizationHandler<MyPolicyRequirement> 
{ 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyPolicyRequirement requirement) 
    { 
     if (!context.User.Identity.IsAuthenticated) 
      return Task.CompletedTask; 


     if (context.User.Identities.FirstOrDefault().HasClaim(System.Security.Claims.ClaimTypes.Role, requirement.Policy)) 
     { 
      context.Succeed(requirement); 
      return Task.CompletedTask; 
     } 

     return Task.CompletedTask; 

    } 
} 

La validation échoue parce que le context.User.Identity.IsAuthenticated est faux, l'identité des objets n'a aucune prétention aussi bien. Il semble qu'il manque quelque chose dans le Pipeline pour convertir mon authentification de support en une identité d'utilisateur.

Des suggestions?

+0

Avez-vous appelé 'App.UseAuthentication' dans votre pipeline? – leastprivilege

+0

Désolé - j'ai oublié cette partie. La partie Configure du démarrage d'IdentityServer contient: 'app.UseIdentityServer();' La partie Configure du Startup.cs de l'API: 'app.UseCors (" default "); app.UseAuthentication(); app.UseMvc(); ' – MStrojek

+0

Je voulais dire le pipeline api – leastprivilege

Répondre

0

Enfin trouvé le problème: J'ai eu une référence à Microsoft.IdentityModel.Tokens (5.2.0-preview1) en raison de du code pour charger le certificat de signature.

Si ce package est activé, la validation échoue.

Une fois j'ai commencé par valider le certificat de signature du jeton par moi-même donc j'avais besoin de ce composant mais je suppose que tout cela sera géré automatiquement dans la partie AddIdentityServerAuthentication? Donc, la vérification de la politique n'était pas le problème. Merci de me demander de commencer à partir de la base.