需要帮助调试JwtSecurityTokenHandler(web api owin auth / resource servers)

时间:2015-12-07 16:05:54

标签: asp.net-web-api2 owin jwt

我拼命想知道为什么我一直从资源服务器获得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);
    }

这是我的配置和配置WebApi:

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类),并且只是覆盖了我所能做的一切,调用了基本操作。从我所看到的,默认实现没有问题读取令牌(所有预期的值都在那里)。

那么如何测试验证呢? 调用以下三种方法(按此顺序): ReadToken CanReadToken ValidateToken(out validatedToken) * ValidateSignature * ReadToken * CanReadToken * ValidateIssuerSecurityKey * ValidateLifetime * ValidateAudience * ValidateIssuer * CreateClaimsIdentity ValidateToken完成

现在out参数看起来很好。然而,SecurityKeys是0而Id是null(任何相关性?) 内部JwtSecurityToken有一个签名密钥,其中32字节数组符合我的预期。 如果我查看非公共成员,则所有4个rawXXX字段都有值(数据,标题和有效负载按预期方式(不知道如何制作rawSignature)) 我使用“https://localhost”作为发行者,也可以从经过验证的令牌中读取。

在完成所有这些之后,我在自己的自定义AuthorizeAttribute中覆盖了OnAuthorizationAsync。在这里,我调用基本实现(AuthorizeAttribute中的实现),actionContext始终以401失败。

我必须承认我真的无法弄明白为什么!

1 个答案:

答案 0 :(得分: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之前更改配置?