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?
Avez-vous appelé 'App.UseAuthentication' dans votre pipeline? – leastprivilege
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
Je voulais dire le pipeline api – leastprivilege