Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core 3.1 + Angular 9 role based authentication

I have created a web application with ASP.NET Core 3.1 and angular with the Visual Studio Template and enabled Authentication. enter image description here
Then I scaffolded the Identity and added this to the Startup.cs:

services.AddDefaultIdentity<ApplicationUser>(options => 
options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();

services.AddIdentityServer().AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

services.AddAuthentication().AddIdentityServerJwt();

After that I have created 3 users and assigned them different roles. When I add the Attribute [Authorize] to any controller action it works correctly. But how can I make it role based? I have tried [Authorize(Roles = "Administrator")] But it denied the access. On an unprotected method:

 var loggedinUser = await _userManager.FindByNameAsync(userid);
 var roles = await _userManager.GetRolesAsync(loggedinUser);

the roles list has the Administrator on it, so I do not know what I am missing to make it work. Also inside an Angular component, how can I get the role of the current logged in user?

like image 513
Momo Avatar asked Jun 18 '20 22:06

Momo


Video Answer


1 Answers

You can extend the implementation of default ProfileService of IdentityServer to include role claim like following way.

public class ExtendedProfileService : ProfileService<ApplicationUser>
{
    public ExtendedProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory) : base(userManager, claimsFactory)
    {

    }

    public override async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        await base.GetProfileDataAsync(context);
        var user = await UserManager.GetUserAsync(context.Subject);
        var roles = await UserManager.GetRolesAsync(user);
        var claims = new List<Claim>();

        foreach (var role in roles)
        {
            claims.Add(new Claim("role", role));
        }
        context.IssuedClaims.AddRange(claims);
    }
}

And don't forget to register your extended profile service to dependency container

services.AddTransient<IProfileService, ExtendedProfileService>();
like image 113
Sithira Pathirana Avatar answered Oct 17 '22 22:10

Sithira Pathirana