2017-10-06 8 views
1

Mon problème: [Authorize (rôles = « L1 »)] et User.IsInRole (« L1 ») cherchent le nom de réclamation « http://schemas.microsoft.com/ws/2008/06/identity/claims/role » au lieu du "rôle"Comment configurer le nom de réclamation de rôle dans IdentityServer4/Identité

dans le béton: J'ai créé un IdentityServer4 avec la base de données d'identité standard par les étapes suivantes (http://docs.identityserver.io/en/release/quickstarts/6_aspnet_identity.html):

  • Créer un nouveau projet
    • ASP.NET de base (Web Application .NET de base)
    • ASP.NET Core 1.1
    • application Web
    • changement d'authentification
      • comptes utilisateurs individuels
  • Ajouter IdentityServer4.AspNetIdentity + Config.cs + ...

Puis j'ai créé un client MVC. L'authentification fonctionne correctement. J'ai aussi une liste de réclamations.

J'utilise les tables AspNetUsers, AspNetUserRoles et AspNetRoles pour que IdentityServer4 configure le rôle. Les rôles sont ajoutés aux revendications avec le nom de revendication "rôle".

Si j'essaie d'autoriser mes actions de contrôleur dans MVC-Client, il semble que le nom de la revendication pour mes rôles est erroné.

Comment puis-je résoudre le conflit? Dois-je associer "rôle" à "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"?

Voici mon contrôleur dans le MVC-Client:

[Route("api/[controller]")] 
public class CompaniesController : Controller 
{ 
    [HttpGet] 
    //[Authorize(Roles = "L1")] // This looks for the claim http://schemas.microsoft.com/ws/2008/06/identity/claims/role instead of role 
    public async Task<IEnumerable<Company>> GetCompaniesAsync() 
    { 
     var c = User.Identities.Count(); // 1 
     var nameOfExptectedRoleClaimType = User.Identities.First().RoleClaimType; // http://schemas.microsoft.com/ws/2008/06/identity/claims/role 
     var b0 = User.HasClaim(nameOfExptectedRoleClaimType, "L1"); // false 
     var b1 = User.HasClaim("role", "L1"); // true 
     var b2 = User.IsInRole("L1"); // false; looks for claim http://schemas.microsoft.com/ws/2008/06/identity/claims/role; used by [Authorize(Roles = "L1")] 

     var companies = await _crmApi.GetCompaniesAsync(); 

     return companies; 
    } 
} 

J'ai trouvé cette réponse (https://stackoverflow.com/a/34226538/272357) mais je ne sais pas comment "registre" CustomPrinciple.

+1

La réponse trouvée ne fonctionne pas avec asp.net-core car un UserManager avec le paramètre ClaimsPrinciple générique n'existe pas dans Microsoft.AspNetCore.Identity. – Nikolaus

Répondre

2

J'ai trouvé une réponse pour moi-même. Je dois mentionner que j'utilise JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); pour éviter le changement de nom des noms de revendications (voir le code).

Le problème résultant était que ClaimsPrinciple recherche toujours les rôles nommés avec "http://schemas.microsoft.com/ws/2008/06/identity/claims/role".

Ceci pourrait être corrigé indirectement avec OpenIdConnectOptions.TokenValidationParameters.

public class Startup 
{ 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
    // ... 

    // Avoid claim mapping to old ms soap namespaces. Avoid replace "role" by "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" 
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); 

    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions 
    { 
     // ... 

     // https://leastprivilege.com/2016/08/21/why-does-my-authorize-attribute-not-work/ 
     TokenValidationParameters = new TokenValidationParameters 
     { 
     NameClaimType = "name", 
     RoleClaimType = "role", // The role claim type is named "role" instead of "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" 
     } 

    }); 
    } 
}