天天看点

IdentityServer4登录后无法跳转samesite=none

IdentityServer4登录后无法跳转samesite=none

 前言

  公司使用id4进行认证授权,已经有一年了,但是今年2月份突然出现某些用户登录之后,无法跳转回原网页,还是停留在登录页。远程查看出现问题的客户,发现问题并不是必然出现,而是偶然几次,之后再次输入密码就可以正常登录了。

  最后发现原来是今年2月份chrome浏览器的cookies政策有改动,导致某些版本浏览器无法成功写入cookies导致的。下面链接是我找到的解决方案,老外写的,供参考。

https://www.thinktecture.com/en/identity/samesite/prepare-your-identityserver/

排查过程

       首先观察了请求的流程

IdentityServer4登录后无法跳转samesite=none

上图右边的第一个请求就是登陆接口,这里登陆返回的是成功的,然后会跳转到主页,然后主页面通过/connect/authorize来验证用户相关权限。

       不过验证的过程,IdentityServer4却返回了无权限,所以导致又回到了登录页面。这个过程在用户的感知中就是点击了登录,也提示了登录成功,可是过了一会,页面还是停留在登录页。

       然后看了下id4的判定用户是否登录的代码,如下

IdentityServer4登录后无法跳转samesite=none

他是通过UserSession来获取用户状态的,这个UserSession有不同的实现模式,默认是下面的cookie-based的Session

IdentityServer4登录后无法跳转samesite=none

       然后看了下登录失败的浏览器cookies情况,如下

IdentityServer4登录后无法跳转samesite=none

成功的情况应该是如下

IdentityServer4登录后无法跳转samesite=none

idsrv和idsrv.session就是id4保存用户登录状态的cookies,这里idsrv是维持长期登录状态的的cookies,哪怕用户关掉浏览器,再次打开到公司主页,也能通过这个cookie进行认证,idsrv.session是本次对话的登录标识,是短期的登录状态标识,这里从Expires的时间也能看出来。

既然是cookie没有成功写入,那么自然是查看请求的返回值,是否正确的返回了set cookie

请求内容

正常的情况

IdentityServer4登录后无法跳转samesite=none

失败的请求内容

IdentityServer4登录后无法跳转samesite=none

仔细对比了下,如下

成功情况

Set-Cookie: idsrv.session=8ae738c38e3cbd358452d0b6303960b7; path=/; secure

失败情况

Set-Cookie: idsrv.session=e524bbd54edc80bf247ea69191e43df8; path=/; secure; samesite=none

idsrv的set请求也是差别也是如此,那么看来很可能就是samesite=none配置在某些浏览器会导致cookies无法正常写入。

解决方案

所以在中间件中手动改变samesite属性为lax即可。

services.Configure<CookiePolicyOptions>(options =>
{
   options.MinimumSameSitePolicy = SameSiteMode.Lax;
   options.OnAppendCookie = cookieContext =>
      CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
   options.OnDeleteCookie = cookieContext =>
      CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
private static void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
   if (options.SameSite == SameSiteMode.None)
   {
      var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
      if (DisallowsSameSiteNone(userAgent))
      {
         options.SameSite = SameSiteMode.Lax;
      }
   }
}      

继续阅读