首页 文章

如何使用Identity&Entity Framework管理.NET Core 2.0中的身份验证和身份验证

提问于
浏览
0

Introduction

在过去的几天里,我一直在小型宠物项目上工作,目标是学习由Entity Framework Core支持的.NET的.NET Core 2.0 . 它是典型的“WebAPI”类型项目,具有基于cookie的身份验证和基于声明的授权 . 它被一些客户端应用程序(SPA)使用 .

Code

授权和身份验证流程在Startup.cs中以这种方式配置

services
    .AddIdentity<ApplicationUser, IdentityRole> ()
    .AddEntityFrameworkStores<ApplicationDbContext> ()
    .AddDefaultTokenProviders ();

services
    .AddAuthentication (sharedOptions => {
        sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    })
    .AddCookie ();

我的登录控制器操作如下所示:

[HttpPost]
[Route ("login")]
public async Task<IActionResult> Login ([FromBody] LogInCredentialsModel credentials) {
    // Get User for given UserName
    var user = await userManager.Users.FirstOrDefaultAsync (p => p.UserName == credentials.UserName);

    //User not found
    if (user == default (ApplicationUser))
        return StatusCode (400);

    // Check if password is correct
    var result = await signInManager.PasswordSignInAsync (user, credentials.Password, true, false);

    if (result.Succeeded) {
        //Basic claims with Name and Email
        List<Claim> claims = new List<Claim> {
            new Claim (ClaimTypes.Name, user.UserName),
            new Claim (ClaimTypes.Email, user.Email)
        };

        var userRoles = await this.GetUserRoles (user); // Custom helper method to get list of user roles

        // Add Role claims
        foreach (var role in userRoles) {
            claims.Add (new Claim (ClaimTypes.Role, role));
        }

        ClaimsIdentity identity = new ClaimsIdentity (claims, CookieAuthenticationDefaults.AuthenticationScheme);
        ClaimsPrincipal principal = new ClaimsPrincipal (identity);

        // Sign in using cookie scheme
        await HttpContext.SignInAsync (CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties {
            IsPersistent = true,
        });

        return Ok ();
    } else {
        return StatusCode (400);
    }
}

Problems

  • 这些声明将存储在加密的用户cookie中 . 这意味着,如果我从用户那里删除了一些索赔并且他没有重新登录,他仍然会分配旧索赔 . 我该如何预防呢?还是我误解了设计?

  • 用户将UserName和Password传递给登录路由,然后用于登录 . 在我的代码中,我必须首先找到具有给定UserName的用户(第一次数据库命中),然后尝试使用SignInManager输入密码(第二次数据库命中) ),读取角色(第3次数据库命中)以构建ClaimsPrincipal,然后使用HttpContext.SignInAsync,以便创建具有正确声明的用户cookie . 我个人觉得我错过了一些东西,结果我的代码过于复杂,至少有一个数据库查询可以保存在这里 . 如何改进这部分?

1 回答

  • 1

    你的两个问题的答案都是非常基本的,所以也许你应该花更多的时间在文档上来更好地处理这个问题 . 那说:

    • 是的 . 你是对的 . 更改声明时,您也应该签署用户 . 然后,您可以选择在没有用户干预的情况下再次自动登录,或者提示用户重新登录(取决于您的个人安全首选项) .

    • 为什么要手动完成所有这些操作?所有你需要的是:

    var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
    

    这会自动散列密码,尝试使用该用户名(电子邮件地址)和散列密码检索用户,然后创建包含所有信息的 ClaimsPrincipal ,如果成功的话 . 一个完成 .

相关问题