.Net核心身份验证和用户会话

时间:2019-02-21 20:56:32

标签: authentication .net-core authorization

我是.Net Core的新手(当前使用.Net Core 2.2)授权和身份验证。 我必须在新项目中开发身份验证和授权机制。在网上搜索时,我发现了几种实现方式(使用身份,不使用,使用Cookie,使用JWT等)。 我希望有人指出适合我的情况的某个方向。这是要求:

  • 我正在将应用程序开发为API。所以我需要保护我的端点。
  • 身份验证将由客户提供的第3部分系统完成。基本上,在我的Login端点中收到用户名和密码后,我将必须请求此服务。然后该服务会告诉我用户是否通过身份验证以及其角色。
  • 经过身份验证后,我将查询自己的数据库以获取有关该用户的信息:其时区,语言等。我希望在会话中获取此信息,因此,来自该用户的每个到达我服务器的请求,我获取语​​言,例如,以正确的语言返回数据。
  • 该应用程序将在负载平衡的情况下部署在两台不同的服务器中。登录一台服务器的用户在另一台服务器上应该是有效的(服务器必须以某种方式共享cookie /令牌)。

我对这里的很多东西不熟悉。我不知道是否可以在服务器之间共享cookie身份验证,还是应该使用JWT并将其持久保存在数据库中?此外,Session如何在.Net core中工作?我可以以某种方式将会话绑定到JWT或类似的东西吗?

哪种方法最好/推荐?

非常感谢您的帮助/教程。

谢谢!

1 个答案:

答案 0 :(得分:2)

只是一些概念:

身份是一个用于帮助建立和管理用户群(如注册,验证密码,密码重置等)的库。它管理存储,安全性和许多必需的验证。这部分似乎由您的客户管理。这样您就不需要了。

Web应用程序通常使用

Cookies /会话来跟踪当前用户信息。虽然可以将这些与Web API一起使用,但实际上不建议也不做。

JWT 用于无状态设置。 Web API大多是无状态(REST)。这意味着最低使用量或RAM,而不使用RAM或数据库来跟踪状态(以了解先前的请求是否与当前请求有关)。 JWT接收用户数据,并使用您可以提供的秘密字符串签名并创建签名。您可以在https://jwt.io等网站上在线阅读有关JWT的更多信息。

您的第一步是连接到客户端的系统以进行身份​​验证。由于您打算连接到服务器端的另一个API,因此需要使用.NET Core的AddHttpClient功能。首先,创建一个类似下面的类:

public class MyAuthClient
{
    private readonly HttpClient httpClient;

    public MyAuthClient(HttpClient httpClient)
    {
        this.httpClient = httpClient;
    }

    public Dictionary<string, string> AuthorizeUser(string username, string password)
    {
        // use the httpClient send login and get confirmation from client's system
        if (loginFailed) return null;
        else
        {
            var result = new Dictionary<string, string>();
            result["userData1"] = "value"; // get these values from the http request you have created above.
        }
    }

}

在启动时添加以下内容:

services.AddHttpClient<MyAuthClient>(client => {
    client.BaseAddress = new Uri("https://yourclientsystem.com");
});

现在,要设置JWT身份验证,可以通过多种方式在线查找。我已经建立了一个名为NetCore.Jwt的库,在这种情况下可能会非常有用。如果您不习惯使用它,则可以提取其源代码或在线使用替代方法。 完成此操作后,在您的startup.cs文件中:

ConfigureServices函数中使用以下内容:

services.AddAuthentication(NetCoreJwtDefaults.SchemeName).AddNetCoreJwt(options => 
{
    options.Secret = "yourVerySecretKeyThatYouWillBeSharingBetweenBothServers";
   // you can configure other options here too
});

Configure函数中的以下内容:

app.UseAuthentication();

上面的代码使用JWT为您的应用程序配置身份验证。确保两个应用程序中的Secret字符串相同将有助于确保您在两个应用程序之间共享相同的登录名。在代码中对这样的字符串进行硬编码是不安全的。检查this link,了解如何以安全格式存储内容。 现在,您将需要一个控制器和一个操作,您可以在其中进行用户登录并提供有效的JWT。可以这样设置:

public class AuthController : Controller
{
    private readonly MyAuthClient authClient;

    public AuthController(MyAuthClient authClient)
    {
        this.authClient = authClient;
    }

    public ActionResult<string> Login(string userName, string password)
    {
        var result = authClient.AuthorizeUser(userName, password);
        if (result == null) return BadRequest("invalid login");
        var claims = new List<Claim>();
        foreach (var r in result)
        {
            claims.Add(new Claim(r.Key, r.Value));
        }
        claims.Add(new Claim(ClaimTypes.Name, "usernameHere")); // this can be later accessed using User.Identity.Name
        claims.Add(new Claim(ClaimTypes.NameIdentifier, "userId"));
        string token = HttpContext.GenerateBearerToken(claims);
        return token;
    }

}

最后,要使您的API仅能被授权和使用,请确保在每个控制器的顶部都包含[Authorize]