我有一个使用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?
答案 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)
首先,.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值。