.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
- within
General
, unselect theEnable Just My Code
in Visual Studio - select
Enable Source Link Support
- 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 :
The screenshot of debugging AuthorizeFiler
:
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;