Uma biblioteca auxiliar para implementar o controle de acesso baseado em permissão/atributo (ABAC) com os tokens da Web JSON usando o controle de acesso baseado em políticas (PBAC) do ASP.NET Core.
Crie a enumeração de permissões:
public enum Permissions
{
Create = 0 ,
Read = 1 ,
Update = 2 ,
Delete = 3 ,
}Observe que é importante ter o valor subjacente exato para cada permissão - bagunçá -lo vai mexer as permissões armazenadas!
Além disso, apenas enums com o int como tipo subjacente (o padrão) são suportados atualmente.
Defina os valores de permissão do usuário dentro do seu provedor de identidade usando o PermissionSet :
user . Claims [ ClaimNames . Permissions ] = new PermissionSet < Permissions > ( new [ ]
{
Permissions . Create ,
Permissions . Read ,
} )
. ToCompactString ( ) ;Adicione o manipulador de requisitos da política de permissão com o mesmo nome de reivindicação acima:
services . AddPermissionBasedAuthorization < Permissions > ( options =>
options . PermissionsClaimName = ClaimNames . Permissions ) ; Observe que, se você redefinir a autorização DefaultPolicy em seu aplicativo, o código acima deve ser inserido após sua lógica para fazer com que as políticas de permissão herdem a nova política padrão.
(Opcionalmente) herdar a AuthorizePermission<T> com as permissões específicas Tipo de enum:
public class AuthorizePermissionAttribute : AuthorizePermissionAttribute < Permissions >
{
public AuthorizePermissionAttribute ( Permissions permission )
: base ( permission )
{ }
}Ou crie um método de extensão se estiver usando as APIs mínimas:
public static TBuilder RequirePermission < TBuilder > ( this TBuilder builder , Permissions permission )
where TBuilder : IEndpointConventionBuilder
{
if ( builder == null )
throw new ArgumentNullException ( nameof ( builder ) ) ;
return builder . RequireAuthorization ( new AuthorizePermissionAttribute < Permissions > ( permission ) ) ;
} Decore os controladores/pontos de extremidade com o atributo AuthorizePermission<T> (ou o criado acima):
[ HttpGet ]
[ Authorize ( Permissions . Read ) ]
public IActionResult Get ( )
=> Ok ( ) ;Ou se estiver usando as APIs mínimas:
app . MapGet ( "/" , ( ) => Results . Ok ( ) )
. RequirePermission ( Permissions . Read ) ; O conjunto de permissão está sendo serializado em uma string como um número hexadecimente em que n -th bit representa a presença de uma permissão com o valor subjacente de n .
Por exemplo, considere a seguinte permissão enum:
public enum Permissions
{
Create = 0,
Read = 1,
Update = 2,
Delete = 3,
Manage = 4,
}
Em seguida, a representação binária de um conjunto contendo todas as permissões acima ficaria assim:
1 F - permission string
┌┬┬┤ ┌┬┬┤
0001 1111 - permission bit values
││││ ││││
7654 3210 - bit positions
└┬┘│ ││││
│ │ │││└ Create
│ │ ││└ Read
│ │ │└ Update
│ │ └ Delete
│ └ Manage
└ Not used
Para a desserialização, o acima é feito na ordem invertida.
Além disso, porque, com base no valor da enumeração, podemos calcular a posição de bit específica que precisamos verificar, não precisamos desserializar a string inteira quando verificarmos uma única permissão.
Verificando um único valor de permissão da sequência compacta:
| Método | Significar | Erro | Stddev | Alocado |
|---|---|---|---|---|
| Permissionset_haspermission | 74.17 ns | 1.382 ns | 1.225 ns | - |
Validando um usuário tem uma permissão necessária em sua lista de reivindicações:
| Método | Significar | Erro | Stddev | Alocado |
|---|---|---|---|---|
| PermissoraAuthorizationHandlerbenchmark_HandleReQuirementSync | 359,4 ns | 6.79 ns | 13.25 ns | 144 b |