如何实现JWT身份验证C#

如何实现JWT身份验证C#,c#,asp.net-core,authentication,jwt,C#,Asp.net Core,Authentication,Jwt,我尝试在C#asp.net核心mvc项目中应用jwt生成器。我可以创建jwt令牌并将其用于登录站点。但是看着jwt的实例,我感到困惑,我不确定我的工作是否是jwt的最佳实践。这是我的密码 这个JwtHandler接受tokenoptions类并声明,然后生成token public static class JwtHandler { public static TokenOptions TokenOptions { get; set; } public static Op

我尝试在C#asp.net核心mvc项目中应用jwt生成器。我可以创建jwt令牌并将其用于登录站点。但是看着jwt的实例,我感到困惑,我不确定我的工作是否是jwt的最佳实践。这是我的密码

这个JwtHandler接受tokenoptions类并声明,然后生成token

   public static class JwtHandler
{
    public static TokenOptions TokenOptions { get; set; }

    public static OperationResult<string> GenerateToken(IEnumerable<Claim> claims)
    {
        OperationResult<string> result = new();

        if (TokenOptions == null)
        {
            result.Messages = "Token Options cannot be null."));
            result.IsSuccess = false;

            return result;
        }

        SymmetricSecurityKey secretKey = new(Encoding.UTF8.GetBytes(TokenOptions.SecretKey));

        SigningCredentials signingCredentials = new(secretKey, SecurityAlgorithms.HmacSha256Signature);

        JwtSecurityToken jwt = new
                               (
                                    issuer: TokenOptions.Issuer,
                                    audience: TokenOptions.Audience,
                                    expires: DateTime.Now.AddMinutes(TokenOptions.TokenExpirationInMinutes),
                                    notBefore: DateTime.Now,
                                    claims: claims,
                                    signingCredentials: signingCredentials
                               );

        result.Data = new JwtSecurityTokenHandler().WriteToken(jwt);

        return result;
    }}
这是我的startup.cs

services.AddAuthentication()
                .AddCookie(c =>
                           {
                               c.LoginPath = new PathString("/login");
                               c.LogoutPath = new PathString("/logout");
                           })
                .AddCustomJwtBearer(Configuration);
海关人员

public static void AddCustomJwtBearer(this AuthenticationBuilder builder, IConfiguration configuration)
    {
        TokenOptions tokenOptions = configuration.GetSection("TokenOptions").Get<TokenOptions>();

        JwtHandler.TokenOptions = tokenOptions;

        builder.AddJwtBearer(c =>
                             {
                                 c.TokenValidationParameters = new TokenValidationParameters
                                 {
                                     ValidateIssuer = true,
                                     ValidateAudience = true,
                                     ValidIssuer = tokenOptions.Issuer,
                                     ValidAudience = tokenOptions.Audience,
                                     ValidateIssuerSigningKey = true,
                                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecretKey))
                                 };
                             });
    }
public static void AddCustomJwtBearer(此AuthenticationBuilder,IConfiguration配置)
{
TokenOptions TokenOptions=configuration.GetSection(“TokenOptions”).Get();
JwtHandler.TokenOptions=TokenOptions;
builder.AddJwtBearer(c=>
{
c、 TokenValidationParameters=新的TokenValidationParameters
{
validateisuer=true,
ValidateAudience=true,
ValidIssuer=tokenOptions.Issuer,
Validudience=代币选项。观众,
ValidateSuersigningKey=true,
IssuerSigningKey=new-SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecretKey))
};
});
}
这是我称之为jwthandler的方法

    [HttpPost("/token")]
    public async Task<IActionResult> TokenGenerate([FromBody] UserModel userModel)
    {
        OperationResult<User> userResult = await _userService.LoginAsync(userModel.EmailAddress, userModel.Password);

        if (!userResult.IsSuccess)
        {
            return BadRequest(userResult);
        }

        List<Claim> claims = new()
        {
            new Claim(ClaimTypes.Name, userResult.Data.EmailAddress),
            new Claim("FullName", userResult.Data.FirstName + " " + userResult.Data.LastName),
            new Claim(ClaimTypes.Role, "Administrator")
        };

        OperationResult<string> tokenResult = JwtHandler.GenerateToken(claims);

        return Json(tokenResult);
    }
[HttpPost(“/token”)]
公共异步任务令牌生成([FromBody]UserModel UserModel)
{
OperationResult userResult=wait _userService.LoginAsync(userModel.EmailAddress,userModel.Password);
如果(!userResult.issucess)
{
返回请求(userResult);
}
列出索赔=新()
{
新索赔(ClaimTypes.Name、userResult.Data.EmailAddress),
新声明(“FullName”,userResult.Data.FirstName+“”+userResult.Data.LastName),
新索赔(ClaimTypes.Role,“管理员”)
};
OperationResult tokenResult=JwtHandler.GenerateToken(索赔);
返回Json(tokenResult);
}
所以我想知道我的方法是jwt生成器的最佳实践,或者哪种方法最适合它?
还有一件事,我看到一些人将httpcontext用于jwt令牌,所以我想知道什么时候应该将httpcontext用于jwt,为什么人们会使用它?

我认为更好的做法是使用IdentityServer4或KeyClock之类的东西。您最好在安全方面和时间方面使用一些可以为您生成令牌的东西,这样您就可以专注于业务逻辑。我使用删除的静态实现了该版本,并为处理程序使用了一个接口。我不使用IdentityServer或Keylock,因为我尝试学习“生成令牌并设置声明”业务,但感谢您的回答。我会尽快尝试你的建议@米查尔·罗森鲍姆
    [HttpPost("/token")]
    public async Task<IActionResult> TokenGenerate([FromBody] UserModel userModel)
    {
        OperationResult<User> userResult = await _userService.LoginAsync(userModel.EmailAddress, userModel.Password);

        if (!userResult.IsSuccess)
        {
            return BadRequest(userResult);
        }

        List<Claim> claims = new()
        {
            new Claim(ClaimTypes.Name, userResult.Data.EmailAddress),
            new Claim("FullName", userResult.Data.FirstName + " " + userResult.Data.LastName),
            new Claim(ClaimTypes.Role, "Administrator")
        };

        OperationResult<string> tokenResult = JwtHandler.GenerateToken(claims);

        return Json(tokenResult);
    }