前言

之前有一位购买我课程的童鞋利用最新的IdentityServer4版本即对应.NET Core 3.x,发布到生产环境在学习,结果出了一些问题,此前我并未过多关注IdentityServer4升级到3.x版本,所以在此做一个基本的总结,或许能对出现相同问题的童鞋能提供一点帮助。

IdentityServer4迁移至3.x版本问题

针对将.NET Core 2.x升级到3.x就不用再多讲,请参看官方迁移文档(https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio),我们只介绍对于对于配置IdentityServer4方面的更改变化

.NET Core Identity

对于Identity里面的上下文【IdentityDbContext】需要额外下载包【Microsoft.AspNetCore.Identity.EntityFrameworkCore】

OIDC配置

针对如下客户端OIDC的配置,需要下载包【Microsoft.AspNetCore.Authentication.OpenIdConnect】

授权中间件配置

针对客户端认证和授权配置,需要如下配置授权中间件(认证和授权无先后顺序)

迁移类生成

我们知道在此之前对于迁移命名是包含在dotnet CLI里面,现已修改为通过单独的包来进行,所以我们需要下载包【Microsoft.EntityFrameworkCore.Design】,否则将抛出如下异常

还有可能遇到命令行工具版本和当前.NET Core版本不一致的问题,通过如下命令进行更新

  //使用PowerShell或CMD命令更新

  //更新到指定版本
()dotnet tool update --global dotnet-ef --version 3.1.2 //更新到最新版本
() dotnet tool update --global dotnet-ef

Cookie安全策略问题(划重点)

在本地环境可能么有任何问题,但是到了生产环境,可能会抛出如下错误,我们是不是会一脸懵逼呢。

warn: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[]
'.AspNetCore.Correlation.oidc.x9I39lxuVXliU0_mOAEPEbZy_EPESHQQRvq7LPatX7rv7y_vQi-HKLIwqNacHM62AeKarJVmr_KvjAL7nSX6hdeR' cookie not found.
info: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[]
Error from RemoteAuthentication: Correlation failed..

这要从Cookie的出生故事说起,大约在20年前设计cookie时以及之后重新设计该cookie时,跨站点请求伪造(CSRF)攻击和跟踪用户都不是什么大事,在cookie规范中说,如果为特定域设置了cookie,则浏览器发出的每个请求都会将其发送到该域,无论我们是否直接导航到该域,如果浏览器只是从该域加载资源(即图像),向其发送POST请求或将其一部分嵌入到iframe中,但是还有一种情况,我们并不希望浏览器自动将用户会话cookie发送到服务器,因为这将允许任何网站会执行脚本,该脚本在该用户的上下文中对服务器执行请求,为避免这种情况,于2016年起草了SameSite cookie规范,它使我们可以更好地控制何时应发送和不应该发送cookie,设置cookie时,我们现在可以在浏览器将其添加到其中时为每个cookie明确指定,为此,它引入了当浏览器位于我们自己的域上时相同站点cookie的概念,以及当浏览器导航到另一个域但将请求发送到我们的域时跨站点cookie的概念,为了向后兼容,相同站点cookie的默认设置并不会更改以前的行为,若我们加入该新功能,需要将cookie显式设置为SameSite = Lax或SameSite = Strict,以使其更加安全,这已在.NET Framework和所有常见的浏览器中实现,Lax表示将在初始导航时将cookie发送到服务器,Strict表示仅在我们已经在该域中时(即在初始导航之后发送第二个请求)才发送cookie。但是呢,这项新功能却并没有被广泛采用(基于2019年3月Chrome的遥测数据,Chrome在全球范围内处理的所有cookie中,只有0.1%使用了SameSite标志,Google为了实现推动该新功能的目标,他们决定更改世界上最常用的浏览器的默认设置:Chrome 80将需要新指定的设置SameSite = None来保持处理Cookie的旧方法,并且如果我们像建议的旧规范那样省略SameSite字段的话,它将cookie与SameSite = Lax一起设置,请注意:仅当cookie也被标记为Secure并且需要HTTPS连接时,设置SameSite = None才有效,这里关于更多SameSite的信息就不再阐述。如果我们有一个单页Web应用程序(SPA),该Web应用程序通过另一个域上托管的身份提供程序(例如IdentityServer 4中的Idp)进行身份验证,并且该应用程序使用所谓的令牌刷新,则将会受到影响,登录IdP时,它将为我们的用户设置一个会话cookie,并且该cookie来自IdP域,在身份验证流程结束时,来自不同域的应用程序将收到某种访问令牌,这些令牌通常生命周期并不长,当该令牌过期时,应用程序将无法再访问资源服务器(API),如果用户每次都必须再次登录,可想用户体验之差,为防止这种情况,我们可以使用刷新令牌,在这种情况下,应用程序将创建一个用户不可见的iframe,然后在该iframe中再次启动身份验证过程, IdP的网站已加载到iframe中,并且如果浏览器通过IdP发送会话cookie,则会识别用户并发出新令牌,现在,iframe位于应用程序域中托管的SPA中,其内容来自IdP域,这将被视为跨站点请求,因此,如果Cookie明确指出SameSite = None,则Chrome 80只会将该Cookie从iframe发送到IdP,否则,令牌刷新将在Chrome 80中出现中断的情况。也还有其他可能潜在的问题,如果我们在Web应用程序或网站中嵌入了来自另一个域的元素(例如视频),并且这些元素需要Cookie才能正常运行(例如自动播放设置),那么这些也会需要设置SameSite策略,如果我们的应用程序需要从浏览器请求依赖Cookie身份验证的第三方API,则同样适用,我们只能更改自己服务器从而设置cookie行为。

讲解了这么多貌似好像没有用的废话,实际上就是出现了跨站点安全策略即SameSite的设定,如上异常的抛出,追本溯源在于是什么原因导致了客户端的Cookie丢失?通过上述对Cookie的讲解,我们可以显式设置SameSite安全策略从而保证到底发不发送Cookie,所以我猜测在.NET Core 3.x中是不是更改了Cookie的安全策略,如果客户端的为Strict的话,那就会导致上述异常的发生,比如如下:

说到这里,为了验证我的结论,我立马翻看了关于.NET Core中Cookie对于安全策略的设置,难道真的将Strict作为默认的安全策略吗?

原来该安全策略的默认选项就是Lax(宽松策略),然后继续来到上述的issue(https://github.com/aspnet/Security/issues/1231),在2.0中就解决了此问题将Strict修改为了Lax,就是为了解决OAuth中重定向跳转认证的问题。这个结果虽在意料之中,但是也在意料之外,那位童鞋也遇到了抛出上述异常的问题,我就是显式设置上述安全策略为Lax得到了解决,让我很是纳闷,这是何故,我也不知道,但是确确实实是解决了,最终客户端也正常跑起来了,真是(捂脸)的表情。最后也同样重要的是,IdentityServer4在生产环境中是启用了HTTPS,所以在发布到生产环境后若未使用HTTPS,一定要将启用HTTPS选项显式配置为false,而本地则不然,遇到问题首先分析问题,然后看官方文档,如若还不能解决,只能通过经验来进行可能原因分析了。

总结

本节我只是将IdentityServer4升级到.NET Core 3.x的版本需要注意的问题做了一个粗略的解答,根据我的经验,一部分原因出在对于官方文档概念未详细解导致,另外一部分原因出在由于版本升级导致内置处理出现了更改,但官方文档并未更新,这个最麻烦,出现这样的问题只能硬啃源代码并调试,我也同时将我原先在长沙社区成立时所演讲的IDS4 Demo已更新到了最新.NET Core 3.1.2版本(https://github.com/wangpengxpy/IdentityServer4Sample)。

最新文章

  1. 分析Mysql 5.6的Dockerfile
  2. Shell标准输出、标准错误 >/dev/null 2>&1
  3. http详解
  4. GTD一些问题
  5. 云计算相关的一些概念Baas、Saas、Iaas、Paas
  6. 一个Java方法覆盖的小问题
  7. s3c6410_MMU地址映射过程详述
  8. asp.net将数据库中的数据赋给DropDownList
  9. 官方原版Windows XP SP3(VOL)中文简体版ISO下载
  10. centos安装UCenter 和 UCenter_Home
  11. 什么是UUID?
  12. C#中声明、调用和配置事件的演示源码
  13. MySQL 5.7安装指南
  14. Appium Hybrid混合应用测试——Native切换WebView
  15. OA协同办公软件
  16. 使用别名访问MSSQL Express
  17. CodeSmith无法获取Oracle表注释
  18. idea插件Lombok
  19. 解决国内经常无法访问Google的方法
  20. 建议 for 语句的循环控制变量的取值采用“半开半闭区间”写法

热门文章

  1. 构建Oracle的Docker镜像
  2. js几个常用的弹层
  3. 创建可执行jar包
  4. 主效应|处理误差 |组间误差|处理效应|随机误差|组内误差|误差|效应分析|方差齐性检验|SSE|SSA|SST|MSE|MSA|F检验|关系系数|完全随机化设计|区组设计|析因分析
  5. Object.prototype.toString.call(obj).slice(8,-1)
  6. Xen入门系列二【使用 virt-install 安装虚拟机】
  7. 康耐视软件VisionPro-max-u与VisionPro-plus-u的区别
  8. top和margin-top的区别
  9. python学习笔记(7)数据类型转换
  10. 【Linux_Shell 脚本编程学习笔记五、Oracle JDK1.8 安装shell 脚本】