Microsoft.Identity.Web.UI 在本地工作但在应用服务中不工作

Microsoft.Identity.Web.UI works locally but not in App Service

我一直在尝试将身份验证添加到我的网络应用程序中:https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/1-WebApp-OIDC/1-1-MyOrg

如果我通过 dotnet run 在本地 运行 使用 appsettings.Development.json,我可以按预期使用我的组织凭据登录。当我容器化并部署到 Azure 中的 Web 应用程序时,我没有成功登录。浏览器中的 url 停留在 /signin-oidc 并从默认的 Razor 页面应用转到错误页面。

应用服务日志中有消息说 .AspNetCore.Correlation.OpenIdConnect.[key?] cookie not found

[更新] 身份验证流程适用于我的 phone 但不适用于桌面。

  1. 为什么相同的代码可以在本地运行但不能部署?
  2. 为什么找不到 cookie?
  3. 为什么它适用于 iOS 而不是 Windows?

尝试在启动 class 中删除 app.UseCookiePolicy();。 看看here

或者问题是 IdentityServer 仍在使用 AddDeveloperSigningCredential

您可以在代码中添加证书,它将完美运行

参考here for more info

tl;dr - 在 身份验证设置 中设置同站点 cookie 选项修复了此问题。

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
        Configuration.Bind("AzureAd", options);
        options.NonceCookie.SameSite = SameSiteMode.Unspecified;
        options.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
    });

这似乎是因为应用服务仅强制实施 TLS 并且 处理 TLS 终止。因此,对应用程序的请求始终是 HTTP,即使浏览器 URL 是 HTTPS。这会导致许多问题,首先是重定向 URL 从未匹配,因为身份库使用请求方案来形成重定向 URL。我通过注入重定向 URL rewrite:

来“修复”了这个问题
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    {
        Configuration.Bind("AzureAd", options);
        options.Events ??= new OpenIdConnectEvents();
        options.Events.OnRedirectToIdentityProvider += _fixRedirect;
    });

...

private async Task _fixRedirect(RedirectContext context)
{
    context.Request.Scheme = "https";
    if(!context.ProtocolMessage.RedirectUri.StartsWith("https"))
        context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http", "https");
    await Task.CompletedTask;
}

但是,关联 cookie 似乎也使用相同的 HTTP 请求,因此当重定向返回时,HTTPS 不匹配。放宽 SameSiteMode 明确告诉浏览器(?)允许不同的方案。这就是为什么我的 phone 使用不同的浏览器和不同的 cookie 策略,但桌面没有。 运行 在本地使用开发证书允许方案匹配,因为应用终止了 TLS 而不是应用服务。

我挂接到 CookiePolicyOptions.OnAppendCookie 事件以在调试时检查 cookie 以找出这一点。