identityserver4 Correlation failed

1/11/2022 9:21:56 PM
1128
0

一、简单处理

在使用 identityserver4  p配置好用户登录后,并登录成功后在跳转到clent /signin-oidc  时候报告错误

错误内容为:

Exception: Correlation failed.
    Unknown location
    Exception: An error was encountered while handling the remote login.
    Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()

在clent 端的staup 的configService 中加入以下代码即可,在https 下不会报告此错误,此错误与跨站cookie 相关

services.Configure<CookiePolicyOptions>(options =>
    {
    	options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax;
    });

上面是通常会遇到的情况,还有另外一种情况比较特殊

通常更换域名为https就可以解决这个问题。如果没有https域名,通常可以自签名根证书,配合 hosts解析使用任意域名作为https域名

  1. 配置hosts,增加解析:  127.0.0.1  test.example.com
  2. 自签名CA证书:https://learn.microsoft.com/zh-cn/azure/application-gateway/self-signed-certificates
  3. 使用CA证书生成 站点的证书并安装到服务器

自签名证书同样可以参考这个地址的文章 :https://www.tangyuecan.com/2021/12/17/%E5%B1%80%E5%9F%9F%E7%BD%91%E5%86%85%E6%90%AD%E5%BB%BA%E6%B5%8F%E8%A7%88%E5%99%A8%E5%8F%AF%E4%BF%A1%E4%BB%BB%E7%9A%84ssl%E8%AF%81%E4%B9%A6/

二、指向了下游服务

通常我们的客户端可能会是内网的一个服务,会有一个前置代理,如果代理是直接将域名指向服务那么没什么特别的事情,但是如果代理搭配一个服务名指向了服务此时也会出现这个坑爹的错误

例如xxx.com/api/  指向了你的内网的一个服务 A。我处理这个问题用了一周时间才发现

原因很简单,发生这个错误是因为客户端丢失了    .AspNetCore.Correlation.oidc    .AspNetCore.OpenIdConnect.Nonce   这两个cookie,你在观察的时候会发现你的本地请求明明设置了这两个cookie,但是授权返回后却找不到了。跟进一下你会发现

Set-Cookie: .AspNetCore.Correlation.oidc.Skj-jCuTAz1BV7X3GVUJ4dTKPxW0uvEu89H6wGNLJrM=N; expires=Fri, 28 Jan 2022 09:40:28 GMT; path=/signin-oidc; samesite=lax; httponly
    Set-Cookie: .AspNetCore.OpenIdConnect.Nonce.CfDJ8Gc7Q1g8oe9Dr8Z7DhLwxqWzi1Uhj-Woj10h8WfV6PxSrSFfFSzDQMtTeYAsiLbW36m4XogxaqMeLy95NUPyeI0BYgzyagHi47O0YNqXL-Dp_tEKiK1OcAmlDdgsU_tkpNkIkLsd-9AvDYx1YWT5mLTdj8zMxIbeKdyC1y9kcWoARNY7KPcNgpTTb9_JrFP4bc8V3oP6wMVwOp5n8ADJ_oXig9gsEmJ1EfaJRckMgzDA7spm_FU-AMairQTbDqD6sIz0a00j_A-nGcZayvXmC1w=N; expires=Fri, 28 Jan 2022 09:40:28 GMT; path=/signin-oidc; samesite=lax; httponly

这两个cookie的path 设置到了 /signin-oidc下了,那么修改掉这个path的值就可以了

.AddOpenIdConnect("oidc", options =>{
                     options.CorrelationCookie.Path = "/";
                     options.NonceCookie.Path = "/";
    });

三、顶级跨域

在顶级域名跨域的时候按一二两个处理方式确是行不通的,依然会报告这个错误

下面是我在顶级域名跨域下的处理案例

               .AddOpenIdConnect("oidc", options =>
                  {
                      options.Authority = identityAdminConfiguration.IdentityServerBaseUrl;
                      options.RequireHttpsMetadata = identityAdminConfiguration.RequireHttpsMetadata;
                      options.ClientId = identityAdminConfiguration.ClientId; 
                      options.ClientSecret = identityAdminConfiguration.ClientSecret;
                      options.ResponseType = identityAdminConfiguration.OidcResponseType;
                  
    
    				  //看这里,我的编辑器代码模块无法加粗啊啊啊啊啊啊啊啊********************************
                     1、 options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;
                     2、 options.NonceCookie.SecurePolicy = CookieSecurePolicy.Always;
                     3、 options.CorrelationCookie.SameSite = SameSiteMode.None;
                     4、 options.NonceCookie.SameSite = SameSiteMode.None;
                     5、 options.AuthenticationMethod = Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectRedirectBehavior.FormPost;
                   }

当然,既然涉及到跨域,你可能需要处理客户端的跨域问题,既允许认证中心的跨域请求,加入跨域策略

   services.AddCors(c =>
                {
                    c.AddPolicy("CorsPolicy", policy =>
                    {
                        policy
                        .WithOrigins(Configuration.GetSection("Cors").Get<string[]>())  //appsetting.json中加入 "Cors":["http://xxx1.com",……]
  作为顶级节点
                        .WithMethods("get", "post", "put", "delete")
                        .AllowAnyHeader()
                        .AllowCredentials();  //跨域策略设置为允许凭证
                    });
                });
  app.UseCors("CorsPolicy");

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
                options.Secure = CookieSecurePolicy.Always;
            });

延展阅读:  Cookie的 SameSite属性

全部评论



提问