【发布时间】:2020-05-27 09:26:05
【问题描述】:
我有一个 ASP .NET Core WebAPI,我生成了一个 JWT 令牌用于授权,但每当我发送请求时,我都会收到 401 - Unauthorized。
操作顺序:
1. GET for token
2. GET for user <-- 401
我在 jwt.io 上检查了我的令牌,它是正确的。 当我删除 [Authorize] 属性时一切正常
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
IdentityModelEventSource.ShowPII = true;
var appSettingsSection = Configuration.GetSection("Jwt");
services.Configure<JwtSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<JwtSettings>();
services.AddControllers();
services.AddOptions();
services.AddAuthentication(x =>
{
x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x=>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidAudience = appSettings.Issuer,
ValidIssuer = appSettings.Issuer,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Key))
};
}
);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
CreateToken 方法
public JwtDto CreateToken(string email, string role)
{
var now = DateTime.UtcNow;
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub,email),
new Claim(ClaimTypes.Role, role),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat,now.ToTimestamp().ToString(),ClaimValueTypes.Integer64)
};
var expires = now.AddMinutes(360);
var singingCredentails = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_settings.Key)),SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: _settings.Issuer,
claims: claims,
notBefore: now,
expires: expires,
signingCredentials: singingCredentails
);
var token = new JwtSecurityTokenHandler().WriteToken(jwt);
return new JwtDto
{
Token = token,
Expiry = expires.ToTimestamp()
};
}
GetToken - API
[HttpGet]
[Route("token")]
public IActionResult GetToken()
{
var token = _jwtHandler.CreateToken("test", "user");
return Json(token);
}
GetUser - API
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[HttpGet("{email}")]
public async Task<UserDto> Get(string email)
{
return await _userService.GetUserAsync(email);
}
【问题讨论】:
-
您知道您对 GetUser 的调用有一个格式正确的 Authorization 标头,其中包含令牌? "授权:承载
" -
来自调试输出的消息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:信息:授权失败。 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:信息:AuthenticationScheme:Bearer 被质询。
-
但我的意思是您的客户端(JS 应用程序/邮递员?)正在发送正确的 Auth 标头?如果请求中没有正确的 auth 标头,那么您将始终得到 401。对于测试,使用 Postman 效果很好,并且可以让您对请求进行大量控制。
-
是的,我发送了一个带有 Auth 标头的请求。您可以在这里找到我的代码:github.com/leavinus/GetARide/tree/jwt_problem/GetARide.Api 我为测试创建了 .REST 文件 :)
-
将您的代码与我使用的一些代码进行比较时,它们几乎相同,除了我使用 Auth 策略(启动时的 services.AddAuthorization())并且您使用 Authorize 属性。很抱歉,我无法发现问题。
标签: c# asp.net-core jwt asp.net-core-webapi