在signin-oidc重定向时相关性失败 [英] Correlation failed at signin-oidc redirect

查看:399
本文介绍了在signin-oidc重定向时相关性失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当托管在NGINX负载均衡器后面的虚拟机上时,尝试对.NET Core 3.1 Web应用程序进行身份验证时遇到以下问题(在本地它按预期工作,并且当前负载均衡器中只有一个VM)):

I'm running into the following issue when trying to authenticate an .NET Core 3.1 web application when hosted on a Virtual Machine behind an NGINX Load Balancer (Locally it works as expected and I only have one VM in the load balancer currently):

异常:相关性失败.未知位置

Exception: Correlation failed. Unknown location

异常:处理远程登录时遇到错误.Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

Exception: An error was encountered while handling the remote login. Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

我已经做了大量研究,并尝试了十多个修复程序,但似乎都无效.这是我的代码片段:

I've done a lot of research and have tried a dozen fixes and none of them seem to work. Here is are snippets from my code:

Startup.Configure()

Startup.Configure()

        // Initialize the ping options and get default values from the config
        var pingOptions = Configuration.GetSection("PingOAuthWebOptions").Get<PingOAuthWebOptions>();

        // Testing Stack OVerflow Example
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = "oidc";
        })
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromMinutes(10000);
                options.Cookie.Name = "PINGSESSION";
            })
            .AddOpenIdConnect("oidc", options =>
            {
                options.Authority = pingOptions.Authority;
                options.ClientId = pingOptions.ClientId;
                options.ClientSecret = pingOptions.ClientSecret;
                options.ResponseType = OpenIdConnectResponseType.Code;
                options.GetClaimsFromUserInfoEndpoint = true;
                options.Scope.Add("openid"); // Added this
                options.SaveTokens = true;
                options.Events = new OpenIdConnectEvents()
                {
                    OnRedirectToIdentityProvider = async ctx =>
                    {
                        // Change from "HTTP" to "HTTPS" if requested and necessary
                        if (pingOptions.ForceSecureRedirect && ctx.ProtocolMessage.RedirectUri.StartsWith("http:"))
                        {
                            ctx.ProtocolMessage.RedirectUri = ctx.ProtocolMessage.RedirectUri.Replace("http:", "https:");
                        }

                        await Task.FromResult(0);
                    },
                    OnUserInformationReceived = ctx =>
                    {
                        var accessToken = ctx.ProtocolMessage.AccessToken;
                        var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessToken);
                        var appIdentity = new ClaimsIdentity(jwt.Claims);

                        // Add app role
                        appIdentity.AddClaim(new Claim(ClaimTypes.Role, "Superuser"));

                        ctx.Principal.AddIdentity(appIdentity);
                        return Task.CompletedTask;
                    },
                };
            });

Startup.ConfigureServices()

Startup.ConfigureServices()

        if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

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

            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseSession();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });

最后,我尝试过的一些事情:

And finally, some of the things that I have tried:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
       ForwardedHeaders.XForwardedFor |
       ForwardedHeaders.XForwardedHost |
       ForwardedHeaders.XForwardedProto;
    options.ForwardLimit = 2;  //Limit number of proxy hops trusted
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

app.UseHttpsRedirection();

app.UseHttpsRedirection();

CookiePolicyOptions cookiePolicy =新的CookiePolicyOptions(){安全= CookieSecurePolicy.始终,};

CookiePolicyOptions cookiePolicy = new CookiePolicyOptions() { Secure = CookieSecurePolicy.Always, };

redirectContext.ProtocolMessage.State =options.StateDataFormat.Protect(redirectContext.Properties);

redirectContext.ProtocolMessage.State = options.StateDataFormat.Protect(redirectContext.Properties);

app.Use((context,next)=>{context.Request.Scheme ="https";返回next();});

app.Use((context, next) => { context.Request.Scheme = "https"; return next(); });

推荐答案

更新:经过OP的测试后,看来auth cookie由于大小而被NINNX阻止了.问题已通过更改NGINX配置得到解决: https://unix.stackexchange.com/a/605614

UPDATE: After some testing with OP, it appeared that auth cookies were blocked by NGINX because of size. Issue was resolved by changing NGINX config: https://unix.stackexchange.com/a/605614

proxy_buffers         8 16k;  # Buffer pool = 8 buffers of 16k
proxy_buffer_size     16k;    # 16k of buffers from pool used for headers


能否请您检查一下是否可以在dev中运行以下配置?测试之前在NGINX后面的实例中,请确保已在您的OpenId Connect提供程序中注册了该URL.


Can you please check that you are able to run config below in dev? Before testing instance behind NGINX, make sure you have registered that URL with your OpenId Connect provider.

还要检查X-Forwarded-For和X-Forwarded-Proto是否已传递到您的应用程序.在更换服务器后的几次我都遇到了问题.

Also check that X-Forwarded-For and X-Forwarded-Proto are passed on to your app. I've experienced problems with just that a few times after server changes.

我建议使用干净的应用程序对此进行测试,以作为概念验证(POC).在所有环境中启动并运行POC后,您可以将更改应用于现有代码库.

I recommend testing this with a clean app as a proof-of-concept (POC). When POC is up and running in all enviroments, you can apply the changes to your existing code base.

在Startup.ConfigureServices

In Startup.ConfigureServices

            var openIdConnectSettings = new OpenIdConnectSettings();
            Configuration.GetSection("OpenIdConnect").Bind(openIdConnectSettings);

            services.AddAuthentication(options =>
                {
                    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                .AddCookie()
                .AddOpenIdConnect(options =>
                {
                    options.Authority = openIdConnectSettings.Authority;
                    options.ClientId = openIdConnectSettings.ClientId;
                    options.ClientSecret = openIdConnectSettings.ClientSecret;
                    options.ResponseType = OpenIdConnectResponseType.Code;
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.Scope.Add("openid");
                    options.SaveTokens = true;
                });

在Startup.Configure中

In Startup.Configure

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseCookiePolicy();
        }
        else
        {
            app.UseStatusCodePagesWithReExecute( ...

            // required in order to get https for OpenIdConnect
            // must come before app.UseAuthentication();
            var forwardedHeaderOptions = new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            };
            forwardedHeaderOptions.KnownNetworks.Clear();
            forwardedHeaderOptions.KnownProxies.Clear();
            app.UseForwardedHeaders(forwardedHeaderOptions);
        }

        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();

        ....

配置类

    public class OpenIdConnectSettings
    {
        public string Authority { get; set; }
        public string ClientId { get; set; }
        public string ClientSecret { get; set; }
    }

这篇关于在signin-oidc重定向时相关性失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆