.net核心身份2.1角色授权不起作用

时间:2018-09-26 21:21:36

标签: asp.net-core asp.net-core-mvc asp.net-core-identity

我已经在2.1之前多次实现了基于角色的身份验证。按照步骤搭建新的2.1身份。

我扩展了IdentityUser模型以添加其他字段,登录正常,出现了新字段。

startup.cs配置服务包含

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

我播下了角色

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

然后创建一个用户并添加到角色

        AppUser user = new AppUser();
        user.UserName = "Admin";
        user.Email = "admin@admin.com";
        user.Name = "Administrator";
        user.LockoutEnabled = false;
        user.EmailConfirmed = true;

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

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

一切都成功,并且数据库看起来很好(AspNetUserRoles有链接)

但是,用角色装饰控制器将始终返回未经授权的

       [Authorize(Roles = "Administrator")]

但是,使用[Authorize](无角色)的简单登录检查将起作用。

如何解决这个问题/什么是合并源代码的最简单方法,以便我可以逐步调试[Authorize]标签?

3 个答案:

答案 0 :(得分:5)

如何修复

  

但是,用角色装饰控制器将始终返回未经授权的

  [Authorize(Roles = "Administrator")]

这是2.1版本中的一个已知错误。请参阅issue

我遵循了of using the old api suggested by HaoK and C-BERBER的建议,它现在可以正常工作了。

这是我的DbContext

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

使用旧式api配置身份:

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

最后,注销并重新登录,它现在将按预期运行。

如何调试源代码

我想您不会调试AuthorizeAttribe本身,因为它是在编译时处理的。如果您打算调试AuthorizeFilter,则可以按照以下步骤操作:

点击Tools-> Options-> Debugging

  1. General内,取消选择在Visual Studio中的Enable Just My Code
  2. 选择Enable Source Link Support
  3. Symbols内,确保已选择 Microsoft Symbol Servers

您现在可以调试源代码。但是,由于筛选器的工作方式,您需要在MVC之前设置一个断点。我只是设置了一个虚拟的中间件,该中间件将在MVC路由器处理程序之前进行:

enter image description here

调试AuthorizeFiler的屏幕截图:

enter image description here

答案 1 :(得分:0)

我在声明中添加了角色。然后,它既适用于UI(HttpContext.User.IsInRole("Admin")),也适用于authorize属性([Authorize(Roles = "Admin")])。

Startup.cs文件:

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

在身份验证期间,我为请求添加了角色。

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;

答案 2 :(得分:0)

对于我的ASP.NET Core 3(预览版)+ Angular,解决方案位于 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;
});