没有从JWT令牌创建用户身份

时间:2018-07-26 18:14:04

标签: authentication jwt asp.net-core-webapi

我有一个使用JwtBearer身份验证的.Net Core 2 Web API项目。但是,尽管这在验证我的用户身份和遵守我的控制器上的[Authorize]属性方面是可行的,但从未填充用户标识和声明。我还有更多要做的工作来确保为经过身份验证的用户创建ClaimsIdentity吗?

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
      .AddJwtBearer(options => 
      {
          options.Authority = "https://myTenant.auth0.com";
          options.Audience = "https://localhost:5001/api/v1";
          options.RequireHttpsMetadata = false;

          options.TokenValidationParameters = new TokenValidationParameters
          {
             ValidateIssuer = true,
             ValidateAudience = true,
             ValidateLifetime = true,
             ValidateIssuerSigningKey = true,
             ValidIssuer = "myTenant.auth0.com",
             ValidAudience = "https://localhost:5001/api/v1"
          };
     });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, SystemModelBuilder modelBuilder)
{
   ...
   app.UseHttpsRedirection();
   app.UseAuthentication();
}

我的令牌在jwt.ms上看起来像这样:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
.{
  "profileData": {
     "given_name": "Rodd",
     "family_name": "Harris"
  },
  "iss": "https://myTenant.auth0.com/",
  "sub": "auth0|37b5f5c54fdac",
  "aud": [
     "https://localhost:5050/api/v1/",
     "https://myTenant.auth0.com/userinfo"
  ],
  "iat": 1532628090,
  "exp": 1532629290,
  "azp": "2RdsNtKpUgh_wgB3NI6gxd-OAl",
  "scope": "openid profile email app.client.read"
}.[Signature]

在我的控制器中,我有这样的东西:

[ApiController]
[Route("api/v1/[controller]")]
[Authorize]
public class TestController : ControllerBase
{
    [HttpGet("clients")]
    public async Task<IActionResult> ClientsList()
    {
       //Debugger gets here -- user is authenticated           
       var user = HttpContext.User.Identity.Name; //Always null
       var count = HttpContext.User.Claims.Count(); //Always 0
       var allowed = HttpContext.User.IsAuthenticated;  //Always true
       var type = HttpContext.User.AuthenticationType; //AuthenticationTypes.Federated
       ...
    }

是什么使用户的名称和声明无法创建?

更新

所以我才意识到我实际上是在将声明映射到HttpContext.User.Identity.Claims中。还意识到我的令牌没有可自动映射到身份的名称值。因此,我想我的真正问题是,如何覆盖自定义映射,并将令牌自己映射为Identity?

2 个答案:

答案 0 :(得分:0)

也许可以正确配置以获取此信息:

app.UseIdentity();
app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,


            TokenValidationParameters = new TokenValidationParameters()
            {
                ValidIssuer = _config["Tokens:Issuer"],
                ValidAudience = _config["Tokens:Audience"],
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"])),
                ValidateLifetime = true
            }
        });

并小心将其放在UseMvc()之前;

答案 1 :(得分:0)

由于有了信息herehere,我才知道发生了什么事。

首先,.Net显然试图通过查找由密钥http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name标识的声明来根据令牌声明自动映射。当然,我的令牌中没有这个符号-因此没有默认名称映射。

实际上,我意识到我的令牌中没有传递任何名称-因此我必须在Auth0上设置一个规则以包含要用作名称的内容。 (我在app_metadata中确实有一个名称,但是我需要将其拼凑成单独的值)。

完成后,我只需要告诉.Net使用其他密钥即可在令牌声明列表中找到名称声明。我是这样在Startup.cs中完成的:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
   .AddJwtBearer(options => 
   {
      options.TokenValidationParameters = new TokenValidationParameters
      {
          ...
          //There is no magic to this string -- it is whatever claim key is being
          //issued by the Auth Provider
          NameClaimType = "https://myshcemadefinedkey/preferred_username" 
      }
    }

设置好后,.Net开始使用与具有相应键值的令牌声明关联的值填充User.Identity.Name值。