ASP.NET核心签名与JWT

发布于 2025-02-11 23:22:45 字数 5224 浏览 1 评论 0原文

我正在使用JWT进行身份验证,然后将其存储在cookie中。我想使用 httpcontext.signinasync 登录,我看到了许多基本cookie auth的示例,但没有JWT。

这是我的startup.cs

 services.AddTransient<IUserRepository, UserRepository>();
        services.AddTransient<ITokenService, TokenService>();
        IdentityModelEventSource.ShowPII = true;
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
        {

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
            };
            options.SaveToken = true;
            options.Events = new JwtBearerEvents();
            options.Events.OnMessageReceived = context =>
            {

                if (context.Request.Cookies.ContainsKey("X-Access-Token"))
                {
                    context.Token = context.Request.Cookies["X-Access-Token"];
                }

                return Task.CompletedTask;
            };
        })
          .AddCookie(options =>
          {
              options.Cookie.SameSite = SameSiteMode.Strict;
              options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
              options.Cookie.IsEssential = true;

          });

这里是我的登录(目前正常工作,但它对SignInAsync会更好

public IActionResult Login(LoginModel loginModel, string returnUrl)
        {
            if (string.IsNullOrEmpty(loginModel.UserName) || string.IsNullOrEmpty(loginModel.Password))
            {
            ViewBag.Message = "Nem lehet üres";
            return View("Index",loginModel);
            }

            IActionResult response = Unauthorized();
            var validUser = GetUser(loginModel);

            if (validUser != null)
            {
                generatedToken = _tokenService.BuildToken(_config["Jwt:Key"].ToString(), _config["Jwt:Issuer"].ToString(),
                validUser);

                if (generatedToken != null)
                {
                    Response.Cookies.Append("X-Access-Token", generatedToken, new CookieOptions() { HttpOnly = true, SameSite = SameSiteMode.Strict, Secure=true });
                    Response.Cookies.Append("X-Username", loginModel.UserName, new CookieOptions() { HttpOnly = true, SameSite = SameSiteMode.Strict, Secure=true });
                    //Response.Cookies.Append("X-Refresh-Token", user.RefreshToken, new CookieOptions() { HttpOnly = true, SameSite = SameSiteMode.Strict });
                   // HttpContext.Session.SetString("Token", generatedToken);
                if (returnUrl != null)
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("MainWindow");
                }
            }
                else
                {
                ViewBag.Message = "Nem jo token";
                return View("Index", loginModel);
            }
            }
            else
            {
            ViewBag.Message = "Nem jó user";
            return View("Index", loginModel);
        }
        }

,这是我的代币服务:

public class TokenService : ITokenService
{
    private const double EXPIRY_DURATION_MINUTES = 30;

    public string BuildToken(string key, string issuer, User user)
    {
        var claims = new[] {
        new Claim(ClaimTypes.Name, user.Name),
        new Claim(ClaimTypes.Role, user.Role),
        new Claim(ClaimTypes.NameIdentifier,
        Guid.NewGuid().ToString())
        };

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var tokenDescriptor = new JwtSecurityToken(issuer, issuer, claims,
            expires: DateTime.Now.AddMinutes(EXPIRY_DURATION_MINUTES), signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
    }
    public bool IsTokenValid(string key, string issuer, string token)
    {
        var mySecret = Encoding.UTF8.GetBytes(key);
        var mySecurityKey = new SymmetricSecurityKey(mySecret);

        var tokenHandler = new JwtSecurityTokenHandler();
        try
        {
            tokenHandler.ValidateToken(token, new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidIssuer = issuer,
                ValidAudience = issuer,
                IssuerSigningKey = mySecurityKey,
            }, out SecurityToken validatedToken);
        }
        catch
        {
            return false;
        }
        return true;
    }
}

edit 1-添加了问题

我如何实现httpcontext.signinasyasynasync in这种情况?

im using JWT to Authentication, and I'm storing it in Cookies. I want to use HttpContext.SignInAsync to login, I saw a lot of example with basic Cookie Auth, but not with JWT.

Here is my Startup.cs

 services.AddTransient<IUserRepository, UserRepository>();
        services.AddTransient<ITokenService, TokenService>();
        IdentityModelEventSource.ShowPII = true;
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
        {

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Issuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
            };
            options.SaveToken = true;
            options.Events = new JwtBearerEvents();
            options.Events.OnMessageReceived = context =>
            {

                if (context.Request.Cookies.ContainsKey("X-Access-Token"))
                {
                    context.Token = context.Request.Cookies["X-Access-Token"];
                }

                return Task.CompletedTask;
            };
        })
          .AddCookie(options =>
          {
              options.Cookie.SameSite = SameSiteMode.Strict;
              options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
              options.Cookie.IsEssential = true;

          });

Here is my Login (Its currently working, but it would be bettern with SignInAsync

public IActionResult Login(LoginModel loginModel, string returnUrl)
        {
            if (string.IsNullOrEmpty(loginModel.UserName) || string.IsNullOrEmpty(loginModel.Password))
            {
            ViewBag.Message = "Nem lehet üres";
            return View("Index",loginModel);
            }

            IActionResult response = Unauthorized();
            var validUser = GetUser(loginModel);

            if (validUser != null)
            {
                generatedToken = _tokenService.BuildToken(_config["Jwt:Key"].ToString(), _config["Jwt:Issuer"].ToString(),
                validUser);

                if (generatedToken != null)
                {
                    Response.Cookies.Append("X-Access-Token", generatedToken, new CookieOptions() { HttpOnly = true, SameSite = SameSiteMode.Strict, Secure=true });
                    Response.Cookies.Append("X-Username", loginModel.UserName, new CookieOptions() { HttpOnly = true, SameSite = SameSiteMode.Strict, Secure=true });
                    //Response.Cookies.Append("X-Refresh-Token", user.RefreshToken, new CookieOptions() { HttpOnly = true, SameSite = SameSiteMode.Strict });
                   // HttpContext.Session.SetString("Token", generatedToken);
                if (returnUrl != null)
                {
                    return Redirect(returnUrl);
                }
                else
                {
                    return RedirectToAction("MainWindow");
                }
            }
                else
                {
                ViewBag.Message = "Nem jo token";
                return View("Index", loginModel);
            }
            }
            else
            {
            ViewBag.Message = "Nem jó user";
            return View("Index", loginModel);
        }
        }

And here is my Token service:

public class TokenService : ITokenService
{
    private const double EXPIRY_DURATION_MINUTES = 30;

    public string BuildToken(string key, string issuer, User user)
    {
        var claims = new[] {
        new Claim(ClaimTypes.Name, user.Name),
        new Claim(ClaimTypes.Role, user.Role),
        new Claim(ClaimTypes.NameIdentifier,
        Guid.NewGuid().ToString())
        };

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var tokenDescriptor = new JwtSecurityToken(issuer, issuer, claims,
            expires: DateTime.Now.AddMinutes(EXPIRY_DURATION_MINUTES), signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
    }
    public bool IsTokenValid(string key, string issuer, string token)
    {
        var mySecret = Encoding.UTF8.GetBytes(key);
        var mySecurityKey = new SymmetricSecurityKey(mySecret);

        var tokenHandler = new JwtSecurityTokenHandler();
        try
        {
            tokenHandler.ValidateToken(token, new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidIssuer = issuer,
                ValidAudience = issuer,
                IssuerSigningKey = mySecurityKey,
            }, out SecurityToken validatedToken);
        }
        catch
        {
            return false;
        }
        return true;
    }
}

Edit 1 - Added the question

How can I implement HttpContext.SignInAsync in this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青衫负雪 2025-02-18 23:22:45

我的创业公司如下:

 services.AddAuthentication(options =>
            {
                // custom scheme defined in .AddPolicyScheme() below
                options.DefaultScheme = "JWT_OR_COOKIE";
                options.DefaultChallengeScheme = "JWT_OR_COOKIE";
            })
           // Adding Jwt Bearer  
           .AddJwtBearer(options =>
           {
              ....//do your staff
           }).AddCookie("Cookies", options =>
           {
               options.LoginPath = "/account/login";
               options.ExpireTimeSpan = TimeSpan.FromDays(1);
           }).AddPolicyScheme("JWT_OR_COOKIE", "JWT_OR_COOKIE", options =>
           {
               // runs on each request
               options.ForwardDefaultSelector = context =>
               {
                   // filter by auth type
                   string authorization = context.Request.Headers[HeaderNames.Authorization];
                   if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
                       return "Bearer";

                   // otherwise always check for cookie auth
                   return "Cookies";
               };
               });

添加更多代码:

答案

在登录职位方法中
我将下面添加到索赔中

new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),

,而我的令牌产生如下,当您登录时,您将获得令牌。

var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));

                    var token = new JwtSecurityToken(
                        issuer: _configuration["JWT:ValidIssuer"],
                        audience: _configuration["JWT:ValidAudience"],
                        expires: DateTime.Now.AddHours(3),
                        claims: claims,
                        signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
                        );

                    return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token),
                    expiration = token.ValidTo
                });

结果:

“

My startup like below:

 services.AddAuthentication(options =>
            {
                // custom scheme defined in .AddPolicyScheme() below
                options.DefaultScheme = "JWT_OR_COOKIE";
                options.DefaultChallengeScheme = "JWT_OR_COOKIE";
            })
           // Adding Jwt Bearer  
           .AddJwtBearer(options =>
           {
              ....//do your staff
           }).AddCookie("Cookies", options =>
           {
               options.LoginPath = "/account/login";
               options.ExpireTimeSpan = TimeSpan.FromDays(1);
           }).AddPolicyScheme("JWT_OR_COOKIE", "JWT_OR_COOKIE", options =>
           {
               // runs on each request
               options.ForwardDefaultSelector = context =>
               {
                   // filter by auth type
                   string authorization = context.Request.Headers[HeaderNames.Authorization];
                   if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer "))
                       return "Bearer";

                   // otherwise always check for cookie auth
                   return "Cookies";
               };
               });

Add more code:

Some code in this answer

In Login post method
I add below into the claims

new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),

And my token generated as below, when you login , you will get token.

var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));

                    var token = new JwtSecurityToken(
                        issuer: _configuration["JWT:ValidIssuer"],
                        audience: _configuration["JWT:ValidAudience"],
                        expires: DateTime.Now.AddHours(3),
                        claims: claims,
                        signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
                        );

                    return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token),
                    expiration = token.ValidTo
                });

Result:

enter image description here

违心° 2025-02-18 23:22:45

您是说您想从JWT阅读索赔,并以下面的方式了解cookie身份验证的新票:

var jwtsecuritytoken = new JwtSecurityTokenHandler().ReadToken(token) as JwtSecurityToken;
                    var username = jwtsecuritytoken.Claims.FirstOrDefault(m => m.Type == ClaimTypes.Name).Value;
                     .......
                     //add other logic
                    .........
                        var claims = new Claim[]
                        {
                        new Claim(ClaimTypes.Name, username),
                         ..........
                         };
                        var claimsIdentity = new ClaimsIdentity(claims);
                        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
                    }

Do you mean you want read claims from jwt and ceate a new ticket for cookie authentication as below:

var jwtsecuritytoken = new JwtSecurityTokenHandler().ReadToken(token) as JwtSecurityToken;
                    var username = jwtsecuritytoken.Claims.FirstOrDefault(m => m.Type == ClaimTypes.Name).Value;
                     .......
                     //add other logic
                    .........
                        var claims = new Claim[]
                        {
                        new Claim(ClaimTypes.Name, username),
                         ..........
                         };
                        var claimsIdentity = new ClaimsIdentity(claims);
                        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
                    }
难理解 2025-02-18 23:22:45

只需像在身份验证中间件一样更改身份验证

 services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = "JwtBearerDefaults.AuthenticationScheme";
                options.DefaultChallengeScheme = "JwtBearerDefaults.AuthenticationScheme";
                options.DefaultSignInScheme = "JwtBearerDefaults.AuthenticationScheme";
         
            })

,请自动签名上下文

just change authentication like below

 services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = "JwtBearerDefaults.AuthenticationScheme";
                options.DefaultChallengeScheme = "JwtBearerDefaults.AuthenticationScheme";
                options.DefaultSignInScheme = "JwtBearerDefaults.AuthenticationScheme";
         
            })

authentication middleware do signin context automaticly

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文