c# - 为什么 ASP.NET 中间件不验证令牌?
问题描述
我正在尝试验证传递到 C# 应用程序的 JWT 令牌。我确认每个请求都会发送令牌。如果我手动解码,一切正常(我看到了声明)。但是,当我启用授权时,当我尝试访问该页面时,我会从(Angular)客户端获得 404。我的理论是 Angular 正在发送一个失败的 OPTIONS 请求,因为它无法正确使用令牌进行身份验证。关于如何确认这是问题并解决问题的任何建议?
通过令牌中的声明进行身份验证
[Authorize(Policy = "IsEmployee")]
[HttpGet("TestTokenAccess")]
public JsonResult TestTokenAccess()
{
return Json("token decoded. you have claim IsEmployee=yes");
}
手动令牌解码
[HttpGet("TestDecodeToken")]
public JsonResult TestDecodeToken()
{
//https://shellmonger.com/2015/07/18/decoding-an-auth0-json-web-token-with-c/
if (this.HttpContext.Request.Headers.ContainsKey("Authorization"))
{
var authHeader = this.HttpContext.Request.Headers["Authorization"];
var authBits = authHeader.ToString().Split(' ');
if (authBits.Length != 2)
{
return Json("{error:\"auth bits needs to be length 2\"}");
}
if (!authBits[0].ToLowerInvariant().Equals("bearer"))
{
return Json("{error:\"authBits[0] must be bearer\"}");
}
var secret = "xxxxx";
//Install-Package JWT -Version 4.0.0
try
{
var json = new JwtBuilder()
.WithSecret(secret)
//.MustVerifySignature()
.Decode(authBits[1]);
return Json(json);
}
catch (TokenExpiredException)
{
return Json("Token has expired");
}
catch (SignatureVerificationException)
{
return Json("Token has invalid signature");
}
catch (Exception e)
{
return Json($"other token err: {e.Message}");
}
}
return Json("no token");
}
在 ConfigureServices 中的Startup.cs,但在 AddMVC() 调用之上
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = Configuration["JwtIssuer"];
options.Audience = Configuration["JwtIssuer"];
options.RequireHttpsMetadata = true;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["JwtIssuer"],
ValidAudience = Configuration["JwtIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"]))
};
}
);
services.AddAuthorization(options =>
{
options.AddPolicy("IsEmployee", policy => policy.Requirements.Add(new IsEmployeeRequirement("yes")));
});
services.AddSingleton<IAuthorizationHandler, IsEmployeeAuthorizationHandler>();
应用设置.json
"JwtKey": "xxx",
"JwtIssuer": "http://localhost:44362/",
"JwtExpireDays": 30
web.config 中的片段启用 CORS
<!--added to enable CORS for Angular-->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="https://localhost:44362/" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
解决方案
原来我的问题是Startup.ConfigureServices()
我需要有一个错误指定的声明:
services.AddAuthorization(options =>
{
options.AddPolicy("IsEmployee", policy =>policy.RequireClaim("IsEmployee", "Yes", "yes"));
});
而不是 Microsoft 在此处示例中使用的策略特定方式。我也删除了这AddSingleton()
条线,因为它没有必要
推荐阅读
- python - 出现错误:“模块”对象不可调用
- c# - 从另一个访问 FirstPersonController 脚本以更改值不起作用
- python-3.x - 从 Jenkinsfile 中的 docker 映像激活 conda 环境
- javascript - react-redux 使用 redux 处理多个数据
- javascript - 向 Rails 地图添加多个标记
- python - 如何使用 pyrren python 修复运行时警告以阻止代码执行?
- c++ - boost::asio::steady_timer() vs sleep() 我应该使用哪一个?
- passport.js - Actions on Google 中的帐户与我自己的 OAuth 服务器的关联
- javascript - 将数组中的对象的属性与另一个数组进行比较
- javascript - 用于比较文本的 Javascript 不起作用