如何在控制器方法中使JWT令牌授权可选

时间:2018-02-08 13:07:27

标签: c# asp.net-core jwt asp.net-core-webapi asp.net-core-identity

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

如果JWT令牌失败,我仍然希望命中控制器方法,但ASP.NET Identity User对象将为空。目前,如果身份验证失败,将无法输入控制器方法,因此我无法在方法中应用逻辑来处理我想要作为访客处理的非身份验证用户,而不是阻止它们。

我的代码:

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令牌。

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

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

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

 var loggedInUser = User.Identity.Name;

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

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

3 个答案:

答案 0 :(得分:5)

它实际上比你想象的要容易。您可以使用 AuthorizeAllowAnonymous,如下所示:

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

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

答案 1 :(得分:0)

通过稍微更新ASP.NET Core,除了配置令牌准则之外,还可以使控制器通过添加以下内容来要求Bearer Token身份验证:

Startup.cs

  public void ConfigureServices(IServiceCollection services)
  {
      services.AddJwtSecurity(
                signingConfigurations, tokenConfigurations);
  }

请记住,如果要一次阻止整个控制器,只需将其添加到Authorize类的顶部即可。

namespace <name_controller>
{    
    [Produces("application/json")]
    [Route("api/v1/[controller]")]
    [ApiController]
    [RequireHttps]
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    public class clientesController : Controller
    {
    }
}

答案 2 :(得分:0)

我不确定何时更改,但是我的应用程序在ASP.NET Core 3.1上并且没有我的操作/端点指定我需要授权,但是当有效令牌为时,身份验证中间件仍会在ClaimsPrincipal中提供我所需的信息。如果没有指定令牌,则提供一个空白的主体。