简体   繁体   English

如何在负载均衡器后面配置UseCookieAuthentication

[英]How to configure UseCookieAuthentication behind a load balancer

I am configuring a .netcore application to use OIDC authenication (provided by IdentityServer). 我正在配置.netcore应用程序以使用OIDC身份验证(由IdentityServer提供)。

I have included the following code in my StartUp 我在我的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" },
});

The application is hosted on AWS, within a docker running in ECS. 该应用程序托管在AWS上,在ECS中运行的docker中。 It runs behind an application load balancer listening on https. 它运行在监听https的应用程序负载均衡器后面。

I have found that because my application is not itself using https (because the https is terminated by the load balancer), the OIDC middleware is generating an incorrect return URL when redirecting to the OIDC server - the URL it generates begins http://. 我发现因为我的应用程序本身并不使用https(因为https由负载均衡器终止),OIDC中间件在重定向到OIDC服务器时生成错误的返回URL - 它生成的URL从http://开始。

The return URL is generated by a method named BuildRedirectUri within the AuthenticationHandler base class. 返回URL由AuthenticationHandler基类中名为BuildRedirectUri的方法生成。 It just uses the protocol on which it received the request - there doesn't seem any way to override this. 它只是使用它收到请求的协议 - 似乎没有办法覆盖它。

protected string BuildRedirectUri(string targetPath)
{
    return this.Request.Scheme + "://" + this.Request.Host + this.OriginalPathBase + targetPath;
}

So given it doesn't seem possible to configure the middleware to force a HTTP redirect, what other options do I have? 因此,鉴于似乎不可能配置中间件来强制HTTP重定向,我还有其他选择吗?

Should I write a 'higher' middleware component to listen for redirect requests and modify the protocol? 我应该编写一个“更高”的中间件组件来监听重定向请求并修改协议吗? Or is there a better way to solve this problem? 或者有更好的方法来解决这个问题吗?

When a proxy is used (for example putting IIS in front of Kestrel or as in your case, a load balancer), the proxy should be sending X-Forwarded-For and X-Forwarded-Proto HTTP headers. 使用代理时(例如将IIS放在Kestrel前面或在您的情况下,将负载平衡器放在其中),代理应该发送X-Forwarded-ForX-Forwarded-Proto HTTP头。 It's the latter one that passes along the original protocol that was requested. 后者是通过请求的原始协议传递的。 Fortunately there is a solution, and that is to use the ForwardedHeaders middleware from the Microsoft.AspNetCore.HttpOverrides package. 幸运的是有一个解决方案,那就是使用Microsoft.AspNetCore.HttpOverrides包中的ForwardedHeaders中间件。 So add that package and then add this code to your middleware pipeline: 所以添加该包,然后将此代码添加到中间件管道:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

Place this as early as you can in your pipeline. 尽早将其置于您的管道中。

For me, adding the ForwarededHeaders wasn't enough. 对我来说,添加ForwarededHeaders是不够的。 I had to add to clear the networks and proxies as well (as noted on the ASP.NET Core Docs repo ). 我还必须添加以清除网络和代理(如ASP.NET Core Docs repo中所述 )。

And do so as early as possible in Configure : 并在Configure尽早完成:

 var options = new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        };
 options.KnownNetworks.Clear();
 options.KnownProxies.Clear();
 app.UseForwardedHeaders(options);

If all else fails you can also avoid all this by using the solution posted https://leastprivilege.com/2017/10/09/new-in-identityserver4-v2-simplified-configuration-behind-load-balancers-or-reverse-proxies/ . 如果所有其他方法都失败了,您也可以通过使用https://leastprivilege.com/2017/10/09/new-in-identityserver4-v2-simplified-configuration-behind-load-balancers-or-reverse解决方案来避免这一切。 -proxies / Which also worked (but not for my multi-tenant environment): 哪个也有效(但不适用于我的多租户环境):

services.AddIdentityServer(options =>
            {
                ...
               options.PublicOrigin = "https://whatever.domain.com";
                ...
            })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM