Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.net core identity 2.1 role authorize not working

I've implemented role based auth several times pre 2.1. Followed the steps to scaffold the new 2.1 identities.

I extended the IdentityUser model to add additional fields, login works fine, new fields are present.

startup.cs configure services contains

         services.AddDefaultIdentity<AppUser>()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

I seeded the roles

         IdentityRole role = new IdentityRole();
         role.Name = "Administrator";
         IdentityResult roleResult = roleManager.
         CreateAsync(role).Result;

Then created a user and added to the role

        AppUser user = new AppUser();
        user.UserName = "Admin";
        user.Email = "[email protected]";
        user.Name = "Administrator";
        user.LockoutEnabled = false;
        user.EmailConfirmed = true;

        IdentityResult result = userManager.CreateAsync(user, "password").Result;

        if (result.Succeeded)
        {
            userManager.AddToRoleAsync(user, "Administrator").Wait();
        }

Everything succeeded, and the database looks fine (AspNetUserRoles has links)

However, decorating a controller with a role will always return not authorized

       [Authorize(Roles = "Administrator")]

But, a simple login check with [Authorize] (no role) will work.

How might I fix this/what is the easiest way to incorporate the source code so I can step through/debug the [Authorize] tags?

like image 396
cdurth Avatar asked Sep 26 '18 21:09

cdurth


People also ask

How do I Authorize my net core?

Authorization in ASP.NET Core is controlled with AuthorizeAttribute and its various parameters. In its most basic form, applying the [Authorize] attribute to a controller, action, or Razor Page, limits access to that component to authenticated users. Now only authenticated users can access the Logout function.

How do you do role-based authorization?

Each group has a set of permissions. For role-based authorization, the customer is responsible for providing the user ID, any optional attributes, and all mandatory user attributes necessary to define the user to Payment Feature Services. The customer must also define the roles that are assigned to the user.


2 Answers

How to fix

However, decorating a controller with a role will always return not authorized

  [Authorize(Roles = "Administrator")]

It's a known bug in the version of 2.1 . See issue here .

I follow the advice of using the old api suggested by HaoK and C-BERBER , and it now works flawlessly .

Here's my DbContext:

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

Configure the identity using the old-style api :

services.AddIdentity<AppUser, IdentityRole>()
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddDefaultUI()
        .AddDefaultTokenProviders()
        .AddEntityFrameworkStores<ApplicationDbContext>();

Lastly , logout and re-signin , it will work as expected now .

How to Debug source code

I guess you won't want to debug the AuthorizeAttribe itself , since it is processed at compile-time . If you mean to debug the AuthorizeFilter , you can follow the steps as below :

click Tools -> Options -> Debugging

  1. within General , unselect the Enable Just My Code in Visual Studio
  2. select Enable Source Link Support
  3. within Symbols , make sure that the Microsoft Symbol Servers is selected

And you can debug the source code now . However , due to the way that filter works , you need set a breakpoint before MVC . I just set a dummy middleware that will take place before the MVC router handler :

enter image description here

The screenshot of debugging AuthorizeFiler :

enter image description here

like image 167
itminus Avatar answered Oct 25 '22 13:10

itminus


In my case of ASP.NET Core 3 (preview) + Angular, solution was in AddAuthentication

services.AddDefaultIdentity<ApplicationUser>()
    .AddRoles<IdentityRole>()
    .AddRoleManager<RoleManager<IdentityRole>>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
});
like image 27
baur Avatar answered Oct 25 '22 14:10

baur