在使用 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域名
自签名证书同样可以参考这个地址的文章 :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属性
本文链接:https://blog.nnwk.net/article/44
有问题请留言。版权所有,转载请在显眼位置处保留文章出处,并留下原文连接
Leave your question and I'll get back to you as soon as I see it. All rights reserved. Please keep the source and links
友情链接:
子卿全栈
全部评论