ASP.NET 当托管在 Linux 容器中时,核心在 OAuth 质询中传递 HTTP(而非 HTTPS)重定向 URL
ASP.NET Core passing HTTP (not HTTPS) redirect URL in OAuth challenge when hosted in Linux container
我有一个 Identity Server 4 的实现,它提供了使用 Google 登录的选项。该应用已在 Google 的开发人员控制台注册,并且在 Windows VM 上托管时已经运行了一段时间。
我最近将此应用程序容器化并将其部署到作为 Azure 应用服务托管的 Linux 容器中。我没有更改任何应用程序代码。 Azure 应用程序服务配置为仅提供 HTTPS,并且我已经验证了客户端浏览器和 Cloudflare(我的 DNS 提供商)之间以及 Cloudflare 和 origin 之间的流量都受到 SSL 证书的严格保护。
这是 Google OAuth 按钮的样子。您可以看到这是一个有效的 SSL 连接:
这是注册此 OAuth 提供程序的代码:
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = _externalAuthConfig.Google.ClientId;
options.ClientSecret = _externalAuthConfig.Google.ClientSecret;
});
我已确认客户端和密码有效。这是单击按钮时执行的代码。你看这都是标准的东西。
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[Route("challenge")]
public IActionResult ExternalLogin(
[FromForm] string provider,
[FromQuery] string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
然而,在这个容器化的世界中,当浏览器被重定向到 Google 时,这是我看到的:
注意重定向 URL 中的 http://
。显然错误发生是因为我只注册了 HTTPS 重定向 URL。 Windows VM 上的相同代码 运行 在查询字符串中正确传递了 HTTPS 重定向 URL。我不知道为什么在这个容器化环境中使用这个不安全的 URL。据我所知,唯一的区别是托管基础设施。
以防万一,这个新站点使用内置的 Kestrel Web 服务器,而旧 Windows 版本在前面使用 IIS。
有人知道吗?我被难住了!
通常,我在发布问题后 this SO question 30 分钟在@FerronSW 的回答中找到了解决方案。
解决方案是将以下代码添加到您的 Startup
:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedProto
});
已测试并有效。
我有一个 Identity Server 4 的实现,它提供了使用 Google 登录的选项。该应用已在 Google 的开发人员控制台注册,并且在 Windows VM 上托管时已经运行了一段时间。
我最近将此应用程序容器化并将其部署到作为 Azure 应用服务托管的 Linux 容器中。我没有更改任何应用程序代码。 Azure 应用程序服务配置为仅提供 HTTPS,并且我已经验证了客户端浏览器和 Cloudflare(我的 DNS 提供商)之间以及 Cloudflare 和 origin 之间的流量都受到 SSL 证书的严格保护。
这是 Google OAuth 按钮的样子。您可以看到这是一个有效的 SSL 连接:
这是注册此 OAuth 提供程序的代码:
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
options.ClientId = _externalAuthConfig.Google.ClientId;
options.ClientSecret = _externalAuthConfig.Google.ClientSecret;
});
我已确认客户端和密码有效。这是单击按钮时执行的代码。你看这都是标准的东西。
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[Route("challenge")]
public IActionResult ExternalLogin(
[FromForm] string provider,
[FromQuery] string returnUrl = null)
{
// Request a redirect to the external login provider.
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), new { returnUrl });
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
然而,在这个容器化的世界中,当浏览器被重定向到 Google 时,这是我看到的:
注意重定向 URL 中的 http://
。显然错误发生是因为我只注册了 HTTPS 重定向 URL。 Windows VM 上的相同代码 运行 在查询字符串中正确传递了 HTTPS 重定向 URL。我不知道为什么在这个容器化环境中使用这个不安全的 URL。据我所知,唯一的区别是托管基础设施。
以防万一,这个新站点使用内置的 Kestrel Web 服务器,而旧 Windows 版本在前面使用 IIS。
有人知道吗?我被难住了!
通常,我在发布问题后 this SO question 30 分钟在@FerronSW 的回答中找到了解决方案。
解决方案是将以下代码添加到您的 Startup
:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedProto
});
已测试并有效。