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

Authentication .Net核心身份验证和用户会话,authentication,.net-core,authorization,Authentication,.net Core,Authorization,我不熟悉.NETCore(目前使用.NETCore2.2)授权和身份验证。 我必须在我的新项目中开发身份验证和授权机制。在网上搜索,我找到了几种方法(使用Identity、不使用、使用Cookies、使用JWT等等)。 我希望有人能给我指出一些适合我的情况的方向。以下是要求: 我正在开发一个API应用程序。所以我需要保护我的端点 身份验证将由我的客户提供的第三方系统完成。基本上,在我的登录端点中收到用户和密码后,我必须请求此服务。然后,服务将告诉我用户是否正在进行身份验证及其角色 经过身份验证

我不熟悉.NETCore(目前使用.NETCore2.2)授权和身份验证。 我必须在我的新项目中开发身份验证和授权机制。在网上搜索,我找到了几种方法(使用Identity、不使用、使用Cookies、使用JWT等等)。 我希望有人能给我指出一些适合我的情况的方向。以下是要求:

  • 我正在开发一个API应用程序。所以我需要保护我的端点
  • 身份验证将由我的客户提供的第三方系统完成。基本上,在我的
    登录
    端点中收到用户和密码后,我必须请求此服务。然后,服务将告诉我用户是否正在进行身份验证及其角色
  • 经过身份验证后,我将查询我自己的数据库,以获取有关用户的信息:其时区、语言等。我希望在会话中获得这些信息,以便该用户向我的服务器发出的每个请求都能获取语言,例如,以正确的语言返回数据
  • 应用程序将部署在两个具有负载平衡的不同服务器上。在一台服务器上登录的用户在另一台服务器上应该是有效的(服务器必须以某种方式共享cookie/令牌)
我对这里的很多东西都不熟悉。我不知道是否有可能在服务器之间共享cookie身份验证,或者我应该使用JWT并将其保存在数据库中,也许。。。?另外,会话在.NETCore中是如何工作的?我可以将会话绑定到JWT或类似的东西吗

这里哪种方法最好/推荐

非常感谢您的帮助/指导


谢谢

只是一些概念:

Identity是一个库,用于帮助设置和管理用户群,如注册、验证密码、密码重置等。它管理存储、安全性和许多必需的验证。这部分似乎由您的客户管理。所以你不需要这个

Cookies/session通常由web应用程序用于跟踪当前用户信息。虽然可以将这些与web API一起使用,但实际上不建议这样做,也没有这样做

JWT用于无状态设置。Web API大多是无状态的(REST)。这意味着使用最少的内存或RAM,而不使用RAM或数据库来跟踪状态(以了解前一个请求是否与当前请求相关)。JWT,它获取您的用户数据,使用您可以提供的秘密字符串签名,并创建一个签名。你可以在这些网站上在线阅读更多关于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.AddAuthentication(NetCoreJwtDefaults.SchemeName).AddNetCoreJwt(options => 
{
    options.Secret = "yourVerySecretKeyThatYouWillBeSharingBetweenBothServers";
   // you can configure other options here too
});
app.UseAuthentication();
上面的代码使用JWT配置应用程序的身份验证。确保两个应用程序中的
Secret
字符串相同将有助于确保两个应用程序之间共享相同的登录名。在代码中硬编码这样的字符串是不安全的。检查以了解如何以安全格式存储内容。 现在,您需要一个控制器和操作,在这里您可以进行用户登录并提供有效的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;
    }

}
公共类AuthController:Controller
{
私有只读MyAuthClient authClient;
公共AuthController(MyAuthClient authClient)
{
this.authClient=authClient;
}
公共操作结果登录(字符串用户名、字符串密码)
{
var result=authClient.AuthorizeUser(用户名、密码);
if(result==null)返回BadRequest(“无效登录”);
var索赔=新列表();
foreach(结果中的var)
{
添加(新的索赔(r.Key,r.Value));
}
claims.Add(新声明(ClaimTypes.Name,“usernameHere”);//稍后可以使用User.Identity.Name访问此声明
添加(新索赔(ClaimTypes.NameIdentifier,“userId”);
string token=HttpContext.GenerateBearToken(声明);
返回令牌;
}
}

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

谢谢你,内维尔!我们会尽快深入调查的!一个问题:作为一个无国籍者,建议用什么方式来处理本地化?我是否应该在JWT上添加带有用户偏好的
声明
?(在这种情况下,当用户更改de语言时,必须更新令牌)。我应该在每个请求中发送一个参数并在控制器中设置区域性吗?更新声明与从数据库更新和获取是一个常见的问题。在您的情况下,如果语言将用于大多数请求,您可能希望避免使用db和yes,请更新声明并发回更新的jwt。您还需要考虑将JWT推送到用户可能登录的所有设备。这可以通过web套接字使用
signal
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;
    }

}