需要帮助调试 JwtSecurityTokenHandler(Web api owin 身份验证/资源服务器)

问题描述 投票:0回答:1

我拼命想找出为什么我不断从资源服务器收到 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。

我必须承认我真的不明白为什么!

c# jwt asp.net-web-api2 owin
1个回答
2
投票

我发现了问题所在:

我从这里摘取了这两行:

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 调用中使用配置之前更改配置很重要?

© www.soinside.com 2019 - 2024. All rights reserved.