ASP.NET Core - JWT Bearer Token - Claims, Roles and Policies

Continuamos falando de segurança, porém agora de uma forma mais dinâmica com a utilização das Claims (declarações), as Roles que nada mais são do que Claims do tipo Role e de Policies (políticas).

Eu sugiro que você leia o post ASP.NET Core - JWT Bearer Token - Azure Key Vault, pois nele estão configurações essenciais para o entendimento deste.

Claims, Roles

As Claims são usadas para expôr fragmentos de informações do usuário como Telefone, Endereço, ID do usuário entre outros.
As Roles são usadas para identificar um grupo de usuário que contém características distintas como usuário Administrador, Desenvolvedor, Gestor e assim por diante.

Veja o trecho de código abaixo, temos 3 Claims, mas uma delas é do tipo Role, por fim todas são new da classe Claim.

var securityTokenDescriptor = new SecurityTokenDescriptor  
{
    Subject = new ClaimsIdentity(new Claim[]
    {
        new Claim(ClaimTypes.Name, userModel.Username),
        new Claim(ClaimTypes.Role, userModel.Role),
    }),
    Expires = DateTime.UtcNow.AddHours(2),
    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
        SecurityAlgorithms.HmacSha256Signature)
};
if (!string.IsNullOrEmpty(userModel.Feature))  
    securityTokenDescriptor.Subject.AddClaim(new Claim("Feature", userModel.Feature));

O arquivo abaixo mostra o código por completo, onde as Claims e as Roles são inseridas no token.

Policies

Podemos também configurar Policies que permite que possamos criar uma política de segurança mais rica e robusta como mostrado no código a seguir.

Uma das políticas é chamada de Trusted, ela validar se o usuário está autenticado, se há uma Role (Claim do tipo Role) com valor "Admin" e uma Claim do tipo Feature com o valor "Create".
A outra política é a "CanCreate" onde além de validar se o usuário está autenticado ela exige que haja uma Claim do tipo Feature com o valor "Create", neste caso não temos nenhuma Role.

Authorization

Eu criei 4 endpoints na nossa API de exemplo para poder trabalhar com as Claims, Roles e Policies.

  1. Na action GetRoleManager() somente será permitido o acesso quando o usuário possuir uma Claim do tipo Role "Manager".
  2. Na action GetRole() somente será permitido o acesso quando o usuário possuir uma Claim do tipo Role "Admin" OU "Manager", neste caso vale uma ou outra. Para que isso seja possível, basta indicar as Claims separadas por vírgula [Authorize(Roles = "Admin,Manager")].
  3. Na action GetPolicy() somente será permitido o acesso quando o usuário satisfazer os critérios da policy criada no tópico anterior, neste caso o usuário deve estar autenticado, deve possuir uma Claim do tipo Role "Admin", uma Claim do tipo Feature "Create".
  4. Na action Create() somente será permitido o acesso quando o usuário satisfazer os critérios da policy criada no tópico anterior, neste caso o usuário deve estar autenticado, uma Claim do tipo Feature "Create", neste caso não há necessidade que o usuário senha Admin ou Manager.

No caso das policies é importante destacar que o uso delas na action é pelo nome, "Trusted" para o item 3, "CanCreate" para o item 4.

Você pode conferir qual usuário possui cada uma das características para melhorar e fixar o entendimento, basta gerar o token para este usuário e usar na chamada da api.

Abaixo está o código dos endpoints.

Github

Você pode conferir tudo isso no Github.
Baixe o projeto completo caso tenha dúvidas.