如何解决为什么将授权JWT发送到Web API时会失败?
好的,我正在努力将JWT发送到Web API,并且需要调试方面的帮助。我正在使用Angular 10客户端和ASP.NET Core 2.2作为服务器。我的身份验证流程如下:
向客户端发送的是在服务器中生成的令牌,如下所示:
Claim[] claims = new[] {
new Claim(JwtRegisteredClaimNames.Sub,user.Id),new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),new Claim(JwtRegisteredClaimNames.Iat,new DateTimeOffset(now).ToUnixTimeSeconds().ToString())
// TODO: add additional claims here
};
int tokenExpirationMins = _configuration.GetValue<int>("Auth:JsonWebToken:TokenExpirationInMinutes");
SymmetricSecurityKey issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Auth:JsonWebToken:Key"]));
JwtSecurityToken token = new JwtSecurityToken(
issuer: _configuration["Auth:JsonWebToken:Issuer"],audience: _configuration["Auth:JsonWebToken:Audience"],claims: claims,notBefore: now,expires: now.Add(TimeSpan.FromMinutes(tokenExpirationMins)),signingCredentials: new SigningCredentials( issuerSigningKey,SecurityAlgorithms.HmacSha256));
string encodedToken = new JwtSecurityTokenHandler().WriteToken(token);
// build & return the response
TokenResponseViewModel response = new TokenResponseViewModel()
{
Token = encodedToken,Expiration = tokenExpirationMins,Email = user.Email,User = user.UserName
};
return Json(response);
这很好,客户端从TokenResponseViewModel
获取所有数据。
并且当客户端需要将API请求发送到我的api/user/test
端点时,该请求未经身份验证。请注意,这仅是我试用的机会。它是这样安全的:
/// <summary>
/// POST: api/user/test
/// </summary>
/// <returns>Status code.</returns>
[HttpGet("Test")]
[Authorize]
public IActionResult GetTest()
{
return new OkObjectResult(new { Message = "This is secure data!" });
}
并且由于该请求未通过API认证,因此它正在尝试重定向到http://localhost:50962/Account/Login?ReturnUrl=/api/user/test
:
目前,我不知道如何解决此问题。令牌似乎很好,但是被身份框架拒绝。 JWT未到期,因为到期时间设置为100min。
以下也是我的Angular请求调用:
executeCall(): void {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json','Authorization': 'bearer ' + this.auth.getAuth()!.token
})
};
console.log('executing call');
var url = 'http://localhost:50962/' + 'api/user/test';
this.http.get<string>(url,httpOptions)
.subscribe(
(val) => {
console.log("POST call successful value returned in body",val);
},response => {
console.log("POST call in error",response);
//todo: popup
},() => {
console.log("The POST observable is now completed.");
//todo: popup
});
}
Startup.cs 身份验证设置:
services.AddAuthentication(opts =>
{
opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Auth:Jwt:Issuer"],ValidAudience = Configuration["Auth:Jwt:Audience"],IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Auth:Jwt:Key"])),ClockSkew = TimeSpan.Zero,RequireExpirationTime = true,ValidateIssuer = true,ValidateIssuerSigningKey = true,ValidateAudience = true
};
})
应用设置配置:
"JsonWebToken": {
"Issuer": "http://localhost:50962/","Audience": "http://localhost:50962/","Key": "0pvUGXcvhg1ZRQZGBGy4","TokenExpirationInMinutes": 100
}
解决方法
问题出在这段代码上,我不得不将Authorize
替换为Authorize(AuthenticationSchemes = "Bearer")
:
/// <summary>
/// POST: api/user/test
/// </summary>
/// <returns>Status code.</returns>
[HttpGet("Test")]
[Authorize(AuthenticationSchemes = "Bearer")]
public IActionResult GetTest()
{
return new OkObjectResult(new { Message = "This is secure data!" });
}
基于this article。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。