我正在配置.net核心应用程序以使用OIDC身份验证(由IdentityServer提供)。
我在我的StartUp中包含了以下代码
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
ExpireTimeSpan = TimeSpan.FromMinutes(60)
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = "https://myauthority",
ClientId = "myclient",
CallbackPath = "/",
ResponseType = "id_token token",
Scope = { "openid", "profile", "email" },
});
该应用程序托管在AWS上,在ECS中运行的docker中。它运行在监听https的应用程序负载均衡器后面。
我发现因为我的应用程序本身并不使用https(因为https由负载均衡器终止),OIDC中间件在重定向到OIDC服务器时生成错误的返回URL - 它生成的URL从http://开始。
返回URL由AuthenticationHandler基类中名为BuildRedirectUri的方法生成。它只是使用它收到请求的协议 - 似乎没有办法覆盖它。
protected string BuildRedirectUri(string targetPath)
{
return this.Request.Scheme + "://" + this.Request.Host + this.OriginalPathBase + targetPath;
}
因此,鉴于似乎不可能配置中间件来强制HTTP重定向,我还有其他选择吗?
我应该编写一个“更高”的中间件组件来监听重定向请求并修改协议吗?或者有更好的方法来解决这个问题吗?
使用代理时(例如将IIS放在Kestrel前面或在您的情况下,将负载平衡器放在其中),代理应该发送X-Forwarded-For
和X-Forwarded-Proto
HTTP头。后者是通过请求的原始协议传递的。幸运的是有一个解决方案,那就是使用ForwardedHeaders
包中的Microsoft.AspNetCore.HttpOverrides
中间件。所以添加该包,然后将此代码添加到中间件管道:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
尽早将其置于您的管道中。
对我来说,添加ForwarededHeaders
是不够的。我不得不添加清除网络和代理(如on the ASP.NET Core Docs repo所述)。
并尽快在Configure
这样做:
var options = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
app.UseForwardedHeaders(options);
如果所有其他方法都失败了,您也可以通过使用https://leastprivilege.com/2017/10/09/new-in-identityserver4-v2-simplified-configuration-behind-load-balancers-or-reverse-proxies/发布的解决方案来避免这一切。哪个也有效(但不适用于我的多租户环境):
services.AddIdentityServer(options =>
{
...
options.PublicOrigin = "https://whatever.domain.com";
...
})