我拼命想找出为什么我不断从资源服务器收到 401 响应:
场景: 运行授权服务器的控制台程序。 运行资源服务器的控制台程序。 使用两者(客户端)的控制台程序。
我获取令牌没有问题,并且它通过 jwt.io 上的预期内容进行验证。此外,当提交用于创建令牌的 Base64 编码秘密时,站点还会验证令牌字符串。
我已经尝试了抑制和/或添加 HostAuthentication 默认值/过滤器的所有可能组合;我在 auth 和 webapi use-calls 之前和之后都使用了 UseCors (AllowAll);我什么都试过了!
这是我的配置身份验证:
private void ConfigureAuth(IAppBuilder app, HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter("Bearer"));
var issuer = ConfigurationManager.AppSettings["tokenIssuer"];
var audience = "MyEnergy"; //TODO: audience should be taken from somewhere else!!
var secret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["secret"]); //TODO: no configuration manager here!
var jwtBearerOptions = new JwtBearerAuthenticationOptions()
{
TokenHandler = new testdumbass(),
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
AuthenticationType = "JWT",
AllowedAudiences = new[] {audience},
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
{new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)}
};
app.UseJwtBearerAuthentication(jwtBearerOptions);
}
这是我的配置和ConfigureWebApi:
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
ConfigureAuth(app, config); //using oauth
ConfigureWebApi(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
private void ConfigureWebApi(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
"Default",
"{controller}/{id}",
new {id = RouteParameter.Optional});
}
因此,我尝试实现一个自定义 JwtSecurityTokenHandler (testdumbass 类),并覆盖了我可以覆盖的所有内容,调用基本操作。据我所见,默认实现读取令牌没有问题(所有预期值都在那里)。
那么我该如何测试验证呢? 调用以下三个方法(按顺序): 读取令牌 可以读取令牌 ValidateToken(出validatedToken) *验证签名 *读取令牌 *CanReadToken *验证发行者安全密钥 *验证生命周期 *验证受众 *验证发行人 *创建索赔身份 验证令牌完成
现在输出参数看起来不错。然而,SecurityKeys 为 0,Id 为 null(有相关性吗?) 内部 JwtSecurityToken 有一个签名密钥,其中 32 字节数组符合我的预期。 如果我查看非公共成员,所有 4 个 rawXXX 字段都有值(按预期数据、标头和有效负载(不知道 rawSignature 是什么)) 我使用“https://localhost”作为发行者,也可以从经过验证的令牌中读取它。
完成所有这些之后,我在自己的自定义 AuthorizeAttribute 中重写了 OnAuthorizationAsync。在这里,我调用基本实现(AuthorizeAttribute 中的实现),而 actionContext 总是失败并返回 401。
我必须承认我真的不明白为什么!
我发现了问题所在:
我从这里摘取了这两行:
private void ConfigureAuth(IAppBuilder app, HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter("Bearer"));
并将它们移到这里:
private void ConfigureWebApi(HttpConfiguration config)
{
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter("Bearer"));
config.MapHttpAttributeRoutes();
这将导致在 AuthorizeAttribute 验证中产生具有正确身份的正确上下文(在作为参数发送的 HttpActionContext 中)。
我不明白的是,为什么在 UseWebApi 调用中使用配置之前更改配置很重要?