.net core identity 2.1 role authorize not working

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


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;
});

I added role in claim. Then it works both for UI (HttpContext.User.IsInRole("Admin")) and for authorize attribute ([Authorize(Roles = "Admin")]).

Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{    
    services.AddIdentity<ApplicationUser, IdentityRole>()                
      .AddEntityFrameworkStores<WandContext>();
    ///..... other code
} 

During authentication, I add role to my claim.

var invalidLoginAttempt = false;
var user = await _userManager.FindByNameAsync(loginModel.Email);
if (user != null)
{
    var result = await _signInManager.CheckPasswordSignInAsync(user, loginModel.Password, lockoutOnFailure: true);

    if (result.Succeeded)
    {                                       
        var customClaims = new List<Claim>
        {
            new Claim(ClaimTypes.Role, Role.Admin)
        };

        var claimsIdentity = new ClaimsIdentity(customClaims, CookieAuthenticationDefaults.AuthenticationScheme);
        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme,
            claimsPrincipal, new AuthenticationProperties { IsPersistent = loginModel.RememberMe });

        return LocalRedirect(returnUrl);
    }
    else if (result.IsLockedOut)
        ModelState.AddModelError(string.Empty, "This account has been locked out, please try again later.");
    else
        invalidLoginAttempt = true;
}
else
    invalidLoginAttempt = true;