2

我正在使用 Visual Studio 2015 Enterprise 和 ASP.NET vNext Beta8 构建一个端点,该端点发出和使用 JWT 令牌,如此处详细描述。如该文章中所述,端点使用 AspNet.Security.OpenIdConnect.Server (AKA OIDC) 来完成繁重的工作。

在我们的内部开发环境中建立这个原型时,我们遇到了将它与负载平衡器一起使用的问题。特别是,我们认为这与 app.UseJwtBearerAuthentication 上的“Authority”设置以及我们特殊的 http/https 组合有关。在我们的负载平衡环境中,任何使用令牌调用 REST 方法的尝试都会产生以下异常:

WebException:无法解析远程名称:'devapi.contoso.com.well-known' HttpRequestException:发送请求时出错。
IOException:IDX10804:无法从以下位置检索文档:“ https://devapi.contoso.com.well-known/openid-configuration ”。


考虑以下步骤来重现(这是用于原型制作,不应被视为具有生产价值):

  • 我们使用 OIDC 创建了一个 beta8 原型,如此处所述

  • 我们将该项目部署到运行在 Server 2012 R2 上的 2 个相同配置的 IIS 8.5 服务器。IIS 服务器托管一个名为“API”的 beta8 站点,该站点绑定到所有可用 IP 地址上的主机名“devapi.contoso.com”的端口 80 和 443(为了本文的目的进行了清理)。

  • 两个 IIS 服务器都有一个指向自身的主机条目:

    127.0.0.1 devapi.contoso.com

  • 我们的网络管理员已将 * 证书 (*.contoso.com) 与 Kemp 负载均衡器绑定,并为https://devapi.contoso.com配置 DNS 条目以解析负载均衡器。

  • 现在这很重要,负载平衡器也已配置为使用http将 https 流量代理到 IIS 服务器(不是,重复,不是在 https 上)。已向我解释这是我们公司的标准操作程序,因为他们只需在一个地方安装证书。我们不确定为什么我们的网络管理员在 IIS 中绑定了 443,因为理论上它永远不会在此端口上接收任何流量。

  • 我们通过 https 到https://devapi.contoso.com/authorize/v1发布一个安全的帖子来获取一个令牌,它工作正常(如何制作这个帖子的详细信息在这里):

    {
    “sub”:“todo”,
    “iss”:“ https://devapi.contoso.com/ ”,
    “aud”:“ https://devapi.contoso.com/ ”,
    “exp”:1446158373,
    “ nbf": 1446154773
    }

  • 然后,我们在另一个通过 https 到https://devapi.contoso.com/values/v1/5的安全获取中使用此令牌。

  • OpenIdConnect.OpenIdConnectConfigurationRetriever 抛出异常:

WebException:无法解析远程名称:'devapi.contoso.com.well-known' HttpRequestException:发送请求时出错。
IOException:IDX10804:无法从以下位置检索文档:“ https://devapi.contoso.com.well-known/openid-configuration ”。


我们认为这是因为 OIDC 正在尝试咨询“options.Authority”中指定的主机,我们在启动时将其设置为 https://devapi.contoso.com/。此外,我们推测,由于我们的环境已配置为将负载均衡器和 IIS 之间的 https 流量转换为非 https 流量,因此当框架尝试解析https://devapi.contoso.com/时出现问题。我们已经尝试了许多配置更改,包括甚至将权限指向不安全的http://devapi.contoso.com都无济于事。

任何帮助我们理解这个问题的帮助将不胜感激。

4

1 回答 1

2

@Pinpoint 是对的。此异常是由允许 IdentityModel 发起非 HTTPS 调用的 OIDC 配置代码路径引起的。特别是我们使用的代码示例对授权 URI 中缺少尾部斜杠很敏感。下面是一个代码片段,它使用 Uri 类以可靠的方式组合路径,而不管授权 URI 是否有尾部斜杠:

public void Configure(IApplicationBuilder app, IOptions<AppSettings> appSettings)
{
    .
    .
    .
    // Add a new middleware validating access tokens issued by the OIDC server.
    app.UseJwtBearerAuthentication
    (
        options => 
        {
            options.AuthenticationScheme    = JwtBearerDefaults.AuthenticationScheme                ;
            options.AutomaticAuthentication = false                                                 ;
            options.Authority               = new Uri(appSettings.Value.AuthAuthority).ToString()   ;
            options.Audience                = new Uri(appSettings.Value.AuthAuthority).ToString()   ;

            // Allow IdentityModel to use HTTP
            options.ConfigurationManager = 
                new ConfigurationManager<OpenIdConnectConfiguration>
                (
                    metadataAddress : new Uri(new Uri(options.Authority), ".well-known/openid-configuration").ToString(),
                    configRetriever : new OpenIdConnectConfigurationRetriever()                                         ,
                    docRetriever    : new HttpDocumentRetriever { RequireHttps = false }
                );
        }
    );
    .
    .
    .
}

在此示例中,我们通过“appSettings.Value.AuthAuthority”从 config.json 中提取授权 URI,然后使用Uri类对其进行清理/组合。

于 2015-10-30T15:27:28.850 回答