web-dev-qa-db-fra.com

ASP.NET Core - Ajouter une revendication de rôle à l'utilisateur

J'ai un noyau ASP.NET (basé sur .NET Framework) utilisant l'authentification Windows. Le point est, je dois ajouter une revendication de rôle sur cet utilisateur et ce rôle est stocké dans une base de données distante.

J'ai tellement lu sur OWIN/Cookie/UserManager/UserStore/Identity et ainsi de suite que je suis perdu.

Question: Comment puis-je ajouter une revendication de rôle pour l'utilisateur actuel connecté (Windows) pour l'ensemble de l'application de la manière la plus simple?

Ce dont j'ai besoin, c'est d'utiliser facilement [Authorize(Role= "MyAddedRole")] ou bool res = User.IsInRole("MyAddedRole")

Merci

8
Arnaud F.

En me répondant, alors ce que j'ai fait:

Créer mon propre UserClaimStore (je n'ai besoin que de ce magasin, pas des autres):

public class MyIdentityStore :
    IUserClaimStore<IdentityUser>
{
    private MyDbContext _myDbContext;
    private bool _disposed = false; 

    public MyIdentityStore(MyDbContext myDbContext)
    {
        _myDbContext = myDbContext;
    }

    #region IUserClaimStore
    public Task<IList<Claim>> GetClaimsAsync(IdentityUser user, CancellationToken cancellationToken)
    {
        // logic here to retrieve claims from my own database using _myDbContext
    }

    // All other methods from interface throwing System.NotSupportedException.
    #endregion

    #region IDisposable Support

    protected virtual void Dispose(bool disposing)
    { /* do cleanup */ }
    #endregion
}

Puis créé mon propre ClaimTransformer:

public class MyClaimsTransformer : IClaimsTransformer
{
    private UserManager<IdentityUser> _userManager;

    public MyClaimsTransformer(UserManager<IdentityUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
    {
        var identity = ((ClaimsIdentity)context.Principal.Identity);

        // Accessing the UserClaimStore described above
        var claims = await _userManager.GetClaimsAsync(new IdentityUser(identity.Name));
        identity.AddClaims(claims);

        return await Task.FromResult(context.Principal);
    }
}

Enfin, dans Startup.cs: 

    public void ConfigureServices(IServiceCollection services)
    {
        /* All other stuff here */ 

        // Adding Database connection
        services.AddDbContext<MyDbContext>(o => /* my options */);

        // Associates our database and store to identity
        services.AddIdentity<IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores<MyDbContext>()
            .AddUserStore<MyIdentityStore>();

        // Claims transformation from database to claims
        services.AddTransient<IClaimsTransformer, MyClaimsTransformer>();
    }


    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        /* All other stuff here */ 

        app.UseIdentity();

        app.UseClaimsTransformation(async (context) =>
        { // Retrieve user claims from database
            IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>();
            return await transformer.TransformAsync(context);
        });
    }

Et maintenant je peux utiliser librement [Authorize(Roles = "MyRole")] ou User.IsInRole("MyRole") ou même User.HasClaim(/* */)!

7
Arnaud F.

Vous pouvez ajouter un nouveau rôle dans votre base de données (AspNetRoles), puis l'affecter à l'utilisateur (AspNetUserRoles).

1
vhr

Bien à côté des réponses, je viens de trouver la réponse qui est totalement prédéfinie dans asp .net core. Lorsque vous ajoutez des revendications, il suffit de:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, UserName),
    new Claim(ClaimTypes.Role, "User"),
    new Claim(ClaimTypes.Role, "Admin"),
    new Claim(ClaimTypes.Role, Watever)
};

après cela, vous pouvez simplement l'utiliser comme dit:

[Authorize(Roles = "Watever")]

ou

User.IsInRole("Watever")
1
ashk hp