如何在控制器方法中使 JWT 令牌授权可选 [英] How to make JWT token authorization optional in controller methods

查看:17
本文介绍了如何在控制器方法中使 JWT 令牌授权可选的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 ASP.NET Core 2 Web 应用程序中使用 JWT 令牌

I use JWT tokens in my ASP.NET Core 2 web application

如果 JWT 令牌失败,我仍然希望调用控制器方法,但 ASP.NET 标识 User 对象将为空.目前,如果身份验证失败,将不会输入控制器方法,因此我无法在该方法中应用逻辑来处理我想以访客身份处理而不是阻止他们的未经身份验证的用户.

If the JWT token fails I still want the controller method to be hit but the ASP.NET Identity User object will just be null. Currently the controller method won't get entered if authentication fails so I can't apply logic inside the method to deal with non authenticated users which I want to deal with as guests instead of blocking them.

我的代码:

Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddAuthentication()
            .AddJwtBearer(cfg =>
            {
                cfg.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidIssuer = _config["Tokens:Issuer"],
                    ValidAudience = _config["Tokens:Audience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]))
                };

            });

当用户登录时

   private IActionResult CreateToken(ApplicationUser user, IList<string> roles)
    {
        var claims = new List<Claim>
        {
          new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
          new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
          new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
        };



        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));

        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
          _config["Tokens:Issuer"],
          _config["Tokens:Audience"],
          claims.ToArray(),
         expires: DateTime.Now.AddMinutes(60),
          signingCredentials: creds);

        var results = new
        {
            token = new JwtSecurityTokenHandler().WriteToken(token),
            expiration = token.ValidTo,
        };

        return Created("", results);

我确保在经过身份验证后,各种 API 调用都会传递 JWT 令牌.

I make sure after authenticated the various API calls pass the JWT token.

在我的控制器中,我使用了 Authorize 属性

In my Controller I make use of an Authorize attribute

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
 public class MyController : Controller
{

这允许我使用以下代码捕获登录用户以进行各种 API 调用

This allows me to capture the logged in user with the following code for the various API calls

 var loggedInUser = User.Identity.Name;

如果我删除了授权属性,那么 User.Identity.Name 将始终为 null,即使用户已通过身份验证.

If I remove the authorize attribute then User.Identity.Name will always be null even if the user is authenticated.

如果令牌无效,如何使用授权属性但仍允许输入控制器方法?我想对要输入的授权用户和非授权用户使用相同的方法.然后,我将使用 User.Identity.Name 来确定他们是否未经身份验证,并在他们的方法中包含来宾用户逻辑.

How do I use the authorize attribute but still allow the controller method to be entered if the token is not valid? I want to use the same method for both Authorized and non Authorized users to be entered. I will then use the User.Identity.Name to determine if they are not authenticated and have guest user logic inside the method for them.

推荐答案

这实际上比你想象的要容易.您可以只使用 both AuthorizeAllowAnonymous,如下所示:

It's actually easier than you might expect. You can just use both Authorize and AllowAnonymous, like so:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[AllowAnonymous]
public class MyController : Controller

如果授权成功,您将拥有一个经过身份验证的 User (User.Identity.IsAuthenticated = true),否则,您将拥有一个匿名 User.

If authorization was successful, you'll have an authenticated User (User.Identity.IsAuthenticated = true), otherwise, you will have an anonymous User.

这篇关于如何在控制器方法中使 JWT 令牌授权可选的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆