Azure AD 身份验证 redirect_uri 未在 linux 托管的 (Cloud Foundry) ASP.NET Core 2.2 应用程序上使用 https

Azure AD Authentication redirect_uri not using https on linux-hosted (Cloud Foundry) ASP.NET Core 2.2 application

我有一个 ASP.NET 核心应用程序托管在 SAP Cloud 环境 (Cloud-Foundry) 中的 linux 容器上。

我正在使用 Microsoft.AspNetCore.Authentication.AzureAD.UI 库实施 Azure AD 身份验证。

身份验证失败,因为无论我最初使用什么协议访问 Web 应用程序,它都会使用 http 协议生成 redirect_uri

这失败了,因为它与 Azure 中应用注册中定义的 https url 不匹配。

AADSTS50011: The reply url specified in the request does not match the reply urls configured for the application

在选项中,可以传入CallbackPath,但这只接受相对路径(必须以/开头)。 否则它来自 redirect_url,它是根据 自动生成的。

我不明白的是,即使我直接在浏览器中使用 https 访问应用程序,它仍然在 redirect_uri 中使用 http。

我猜潜在的问题是托管在 Cloud Foundry 中的应用程序接受了 http 请求。

这是我如何实现 Azure AD 身份验证的代码部分。

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
        .AddAzureAD(options => Configuration.Bind("Authentication:AzureAD", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
   {
       options.Authority = options.Authority + "/v2.0";            // Microsoft identity platform
       options.TokenValidationParameters.ValidateIssuer = true;   
   });


 app.UseHsts();
 app.UseHttpsRedirection();


  "Authentication": {
    "AzureAD": {
      "Instance": "https://login.microsoftonline.com/",
      "ClientId": "{app-application-id}",
      "TenantId": "{my-tenant-id}"
    }
  }

您的问题与 this one 类似。不同的是你在cloudfoundry中部署了app,另一个在Azure web app中部署了app。

如果您的应用被迫使用 https,您只需强制 redirect_uri 使用 https

如果你想要一个http和https都可以的通用解决方案(前提是你已经在azure portal中将http和https都配置为重定向url),你可以尝试找到真正的解决方案headers.

中的原型

Tony Ju 为类似问题提供了出色的 link,帮助我缩小并最终解决了我的问题。

但是,该解决方案仅提供代码示例,我想多写一点我是如何实现最终实现的。

当您的应用程序位于代理服务器 and/or 负载平衡器后面时,问题就会出现。代理隐藏了有关初始请求的信息,例如原始模式,使依赖此信息的应用程序中的服务行为不正确(例如 return_url)。

There is an excellent documentation about how to configure your ASP.NET Core application.

根据文档,这是我的问题的根本原因。

When HTTPS requests are proxied over HTTP, the original scheme (HTTPS) is lost and must be forwarded in a header.

the Cloud Foundry Security documentation tells the following

Protocols All traffic from the public internet to the Cloud Controller and UAA happens over HTTPS. Inside the boundary of the system, components communicate over a publish-subscribe (pub-sub) message bus NATS, HTTP, and SSL/TLS.

简而言之,您需要使用标准 Middleware.

转发某些 HttpHeader
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = 
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

app.UseForwardedHeaders();

但是,当您的应用程序部署在没有 IIS 作为代理的 linux 机器上时,.net core 2.1 存在一个已知问题。 当您添加 UseHttpRedirection 中间件时,这会变得更加明显。

摘自this blog post

OAuth and OIDC also fail in this configuration because they generate incorrect redirects. Calls to UseIISIntegration add and configure forwarded headers middleware when running behind IIS, but there’s no matching automatic configuration for Linux (Apache or Nginx integration). The fix for this issue is discussed in more detail in the doc article Forward the scheme for Linux and non-IIS reverse proxies.

这个 post 最终也提供了针对当前情况的工作修复。

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | 
            ForwardedHeaders.XForwardedProto;
        // Only loopback proxies are allowed by default.
        // Clear that restriction because forwarders are enabled by explicit 
        // configuration.
        options.KnownNetworks.Clear();
        options.KnownProxies.Clear();
    });

看起来 .net core 3 不再需要这个,但是 SAP 还没有更新他们的 dotnet 容器,所以我在撰写本文时无法验证它。