Afs*_*bbi 19 authentication jwt asp.net-web-api asp.net-core
我试图JWT
在ASP.NET Core Web API
项目中使用身份验证机制.假设此项目没有MVC
部分,并且不使用cookie身份验证.我已根据本指南创建了我的代码.
登录工作好,保护与[Authorize]
属性工作正常,但User.Identity.Name
就是null
.我怎样才能解决这个问题?
我的代码:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters,
AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Run Code Online (Sandbox Code Playgroud)
[HttpPost]
[AllowAnonymous]
[Route("Login")]
public async Task<IActionResult> Login([FromForm] ApplicationUser applicationUser)
{
//assume user/pass are checked and are ok
_logger.LogInformation(1, "API User logged in.");
var user = await _userManager.FindByNameAsync(applicationUser.UserName);
var roles = await _userManager.GetRolesAsync(user);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, applicationUser.UserName),
new Claim(ClaimTypes.NameIdentifier, applicationUser.UserName),
new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
new Claim(JwtRegisteredClaimNames.Iat,
ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(),
ClaimValueTypes.Integer64),
new Claim("Claim", "Value")
};
if (roles != null)
foreach (var role in roles)
claims.Add(new Claim("role", role));
// Create the JWT security token and encode it.
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims: claims,
notBefore: _jwtOptions.NotBefore,
expires: _jwtOptions.Expiration,
signingCredentials: _jwtOptions.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
// Serialize and return the response
var response = new
{
access_token = encodedJwt,
expires_in = (int)_jwtOptions.ValidFor.TotalSeconds
};
var json = JsonConvert.SerializeObject(response, _serializerSettings);
return new OkObjectResult(json);
}
Run Code Online (Sandbox Code Playgroud)
jps*_*jps 22
在您的声明(第二个代码段)中,我只能看到这个:
new Claim(ClaimTypes.NameIdentifier, applicationUser.UserName),
Run Code Online (Sandbox Code Playgroud)
但你需要添加这个:
new Claim(ClaimTypes.Name, applicationUser.UserName),
Run Code Online (Sandbox Code Playgroud)
那么User.Identity.Name应该包含用户名.
另一种选择是设置命名空间中JwtRegisteredClaimNames.Sub
的tokenValidationParameters
。这将使您继续使用该标准:
var tokenValidationParameters = new TokenValidationParameters
{
// Ensure that User.Identity.Name is set correctly after login
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
... existing code ...
}
Run Code Online (Sandbox Code Playgroud)
更新:Diogo Barros在我的博客上就此主题发表了评论:
“你好,
谢谢您的帮助。这对我有用。为了获得更高的一致性和安全性,可以使用ClaimTypes.NameIdentifier(在System.Security.Claims命名空间中)代替硬编码的字符串。”
我已经更改了代码以使用内置的ClaimTypes枚举,因为它比使用命名空间字符串更优雅。
归档时间: |
|
查看次数: |
6169 次 |
最近记录: |