.net core identity 2.1 role authorize not working

后端 未结 3 492
忘了有多久
忘了有多久 2020-12-10 13:23

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 f

相关标签:
3条回答
  • 2020-12-10 13:29

    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;
    
    0 讨论(0)
  • 2020-12-10 13:33

    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;
    });
    
    0 讨论(0)
  • 2020-12-10 13:38

    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 :

    The screenshot of debugging AuthorizeFiler :

    0 讨论(0)
提交回复
热议问题