Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP .Net Core Identity Role Claims not adding to User

I'm having issues with using Role/Claims.

I have created Roles and given the roles claims. Then assigned these roles to the users, from what I read online this means the User should inherit the Role Claims but they don't. The policy's didn't work and upon further inspection I couldn't see the claims when outputting the user claims via JSON.

All the data is being saved in the database as I can see it.

Role/Claim Seeder

 public static void SeedRolesAndClaims(RoleManager<IdentityRole> roleManager)
    {
        // Create Roles
        IdentityRole adminRole = new IdentityRole("Admin");
        roleManager.CreateAsync(adminRole).Wait();

        roleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "edit.post")).Wait();
        roleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "delete.post")).Wait();
        roleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "create.post")).Wait();
        roleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "view.post")).Wait();
        roleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "create.comment")).Wait();

        IdentityRole userRole = new IdentityRole("User");
        roleManager.CreateAsync(userRole).Wait();
        roleManager.AddClaimAsync(userRole, new Claim(ClaimTypes.AuthorizationDecision, "create.comment")).Wait();

    }

User Seeder

ApplicationUser user = new ApplicationUser { UserName = "[email protected]", FirstName = "Admin", LastName = "Smith", Email = "[email protected]" };
        userManager.CreateAsync(user, "Password123*").Wait();
        userManager.AddToRoleAsync(user, "Admin").Wait();

The check i'm doing is

        var claims = User.Claims.Select(claim => new { claim.Type, claim.Value }).ToArray();
        return Json(claims);

Which returns the basic JSON claims for authentication

[{"type":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier","value":"05bef53e-dd97-41f6-beee-531501cf8598"},{"type":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","value":"[email protected]"},{"type":"AspNet.Identity.SecurityStamp","value":"SGS23ZGIY6UYOOL2APWRIZKNT2V6QBJC"}]

I'm not sure what the issue is and have been searching on google/stackoverflow for a while to no prevail.

Any help would be greatly appreciated

like image 983
denn1s Avatar asked Jan 06 '19 17:01

denn1s


People also ask

How can add custom claims in core identity in asp net?

How to configure and map claims using an OpenID Connect client. Set the name and role claim. Reset the claims namespaces. Customize, extend the claims using TransformAsync.

How do I apply a claim in .NET core?

Adding claims checks Claim based authorization checks are declarative - the developer embeds them within their code, against a controller or an action within a controller, specifying claims which the current user must possess, and optionally the value the claim must hold to access the requested resource.


1 Answers

If you are using .Net Core 2.1 , it seems you will need to change the default Identity configuration according to this issue .

In .Net Core 2.1 , you could firstly create your own ApplicationUser:

public class ApplicationUser : IdentityUser
{
}

Modify your dbcontext :

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole, string>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Configure the identity using the old-style api :

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddDefaultUI()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<ApplicationDbContext>();

And seed the user and role like :

private async Task CreateUserRoles(IServiceProvider serviceProvider)
{
    var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
    var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

    IdentityResult roleResult;
    //Adding Admin Role
    var roleCheck = await RoleManager.RoleExistsAsync("Admin");
    if (!roleCheck)
    {

        IdentityRole adminRole = new IdentityRole("Admin");
        //create the roles and seed them to the database
        roleResult = await RoleManager.CreateAsync(adminRole);

        RoleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "edit.post")).Wait();
        RoleManager.AddClaimAsync(adminRole, new Claim(ClaimTypes.AuthorizationDecision, "delete.post")).Wait();

        ApplicationUser user = new ApplicationUser { UserName = "[email protected]", Email = "[email protected]" };
        UserManager.CreateAsync(user, "xxxxxx").Wait();

        await UserManager.AddToRoleAsync(user, "Admin");
    }

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env ,IServiceProvider serviceProvider)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

    CreateUserRoles(serviceProvider).Wait();
}

At last ,logout and re-signin the account , the claim should be there :

enter image description here

If you are using .Net Core 2.0 , your code should work with the default identity template .

like image 65
Nan Yu Avatar answered Oct 19 '22 23:10

Nan Yu