无法让 App Service CDN 与身份验证一起使用

Unable to get App Service CDN to work with authentication

我有一个 asp.net 核心 Web 应用程序作为应用程序服务托管在 Azure 中。我已将应用程序配置为使用 OpenId Connect 并将 Azure AD 作为授权机构。身份验证发生在我的应用程序中(我没有配置应用程序服务本身来处理身份验证)。

当我直接点击应用服务时一切正常(或者即使我使用自定义域名)。

我在应用服务中启用了 CDN 服务。初始传播完成后,我打开浏览器并导航到 CDN 地址 ([name].azureedge.net).

我得到了一个到 Azure AD 的重定向,但是当我完成身份验证过程后,我得到了一个错误。

看起来当从 CDN 返回到 Azure AD 的重定向时,应用服务的 URL 被设置为 return_url。因此,当 Azure AD 重定向我时,我不再访问 CDN。当重定向到 Azure AD 时,我的浏览器中会放置一个 cookie;我怀疑我的网站正在寻找那个 cookie,但浏览器没有发送它,因为它是由不同的域设置的。

我已经尝试将 OpenIdConnectOptions 中的 CallbackPath 配置为完整 URL(模式、主机、域等),但是当我的应用程序初始化时,抛出错误提示路径必须以一个“/”(大概它期望从请求中域的根目录开始的路径)。

希望其他人遇到过这个问题并能告诉我哪里做错了。

根据请求,这是我的 OIDC 配置:

var openIdOptions = new OpenIdConnectOptions
{
    ClientId = adSettings.ClientId,
    ClientSecret = adSettings.ClientSecret,
    Authority = adSettings.Authority,
    CallbackPath = adSettings.CallbackPath,
    ResponseType = OpenIdConnectResponseType.CodeIdToken,                
    Events = new OpenIdConnectEvents { OnTicketReceived = AddApplicationRolesToUserClaimsAsync, OnAuthorizationCodeReceived = RedeemCodeAsync }
};

foreach (var scope in adSettings.Scopes.Concat(settings.MicrosoftGraph.Scopes))
    openIdOptions.Scope.Add(scope);

application.UseOpenIdConnectAuthentication(openIdOptions);

adSettings 是一个 POCO,由以下 appsettings.json 水合而成:

"AzureAd": {
  "AADInstance": "https://login.microsoftonline.com/",
  "ClientSecret": "REDACTED",
  "CallbackPath": "/signin-oidc",
  "ClientId": "REDACTED",      
  "TenantId": "REDACTED",      
  "Scopes": [
    "openid",
    "profile",
    "offline_access"
  ]
}

adSettings.Authority 在 POCO 中定义为:

public string Authority => $"{AADInstance}{TenantId}/v2.0";

仔细研究后,我找到了答案。

OpenIdConnectOptions.Events 属性 允许您挂钩在身份验证的整个生命周期中发生的各种事件。一个回调称为 OnRedirectToIdentityProvider。它提供了一个RedirectContext。在该对象上,您可以 read/write 到名为 ProtocolMessage.RedirectUri 的 属性。 属性 允许您指定一个完整的 URL,当用户被转发到 AAD 时用作 return_url

值得注意的是,我使用的是 Nuget 的 Microsoft.AspNetCore.Authorization.OpenIdConnect 包。还有其他可用的包提供类似的功能,允许您在选项对象中设置完整的 URL。