c# - User.IsInRole 在 ASP.NET Core 中不返回任何内容(已实现存储库模式)

标签 c# asp.net-core asp.net-identity

我有一个具有以下配置的 ASP.NET Core(完整的 .NET Framework)应用程序:

启动.cs

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>(p => {
        p.Password.RequireDigit = true;
        p.Password.RequireNonAlphanumeric = false;
        p.Password.RequireUppercase = true;
        p.Password.RequiredLength = 5;
    })
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

    services.AddMvc();

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
    services.AddTransient<IDbFactory, DbFactory>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();

    services.AddTransient<IUserRepository, UserRepository>();
    services.AddTransient<IUserService, UserService>();
}

ApplicationUser 扩展自 IdentityUser,ApplicationDbContext 扩展 IdentityDbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base()
    {
    }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public virtual void Commit()
    {
        base.SaveChanges();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder builder)
    {
        base.OnConfiguring(builder);

        builder.UseSqlServer("connection string here");
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);

        // Configure model
        // Identity
        new Configuration.Identity.ApplicationUserConfiguration(builder.Entity<ApplicationUser>());
        new Configuration.Identity.ApplicationUserProfileConfiguration(builder.Entity<ApplicationUserProfile>());
        new Configuration.Identity.RoleConfiguration(builder.Entity<IdentityRole>());
        new Configuration.Identity.RoleClaimConfiguration(builder.Entity<IdentityRoleClaim<string>>());
        new Configuration.Identity.ApplicationUserRoleConfiguration(builder.Entity<IdentityUserRole<string>>());
        new Configuration.Identity.ApplicationUserClaimConfiguration(builder.Entity<IdentityUserClaim<string>>());
        new Configuration.Identity.ApplicationUserLoginConfiguration(builder.Entity<IdentityUserLogin<string>>());
        new Configuration.Identity.ApplicationUserTokenConfiguration(builder.Entity<IdentityUserToken<string>>());
    }
}

这是我的演示数据:

角色表

Role table

用户表

User table

用户角色表

UserRole table

在我的登录操作中,我有以下内容:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, lockoutOnFailure: false);
        if (result.Succeeded)
        {
            if (User.IsInRole("Admin"))
            {
                return RedirectToAction("Index", "Home", new { area = "Admin" });
            }
            return RedirectToAction("Index", "Home");
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning(2, "User account locked out.");
            return View("Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return View(model);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

我想实现的是用户登录后重定向到某个区域。

我目前面临的问题是函数 User.IsInRole("Admin") 返回 false 并且在 Debug模式下,如果我查看 usermanager,当前用户没有加载的角色(计数 = 0)。

如有任何想法,我们将不胜感激。

更新 1

忽略Role Id 原因是错误的。事实上,用户被映射到正确的值。

最佳答案

User.IsInRole 正在检查 cookie。但是您在登录时在同一个 http 请求中检查它。 Cookie 还不存在 - 它将在回复或下一个请求时可用。

此时您需要使用 ApplicationUserManager.IsInRoleAsync(TKey userId, string role) 来检查数据库。

关于c# - User.IsInRole 在 ASP.NET Core 中不返回任何内容(已实现存储库模式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40151224/

相关文章:

asp.net-web-api - 如何使用 Web API 模板中的 AddExternalLogin 方法

asp.net-core - 将 ASP.Net Core 2 Identity 与 Azure Ad 单租户身份验证结合使用

c# - 如何使用复选框动态更改 WPF 控件的模板?

c# - 我可以使用 JWT 进行身份验证,但我的名称声明在 ASP.NET Core 应用程序中无法识别

c# - 有没有办法在 Actions 中选择 Newtonsoft.json 和 System.Text.Json?

c# - 身份用户数据未更新

c# - 如何在删除之前检查一个实体是否已被其他人引用

c# - 如何解决 'Only Parameterless constructors and initializers...' 错误

c# - 无法解决 equal to 操作中 "Cyrillic_General_CI_AS"和 "SQL_Latin1_General_CP1_CI_AS"之间的排序规则冲突

constraints - 标签助手 : Is it possible to add type constraints to a ModelExpression?