对于涉及跨域请求的 SSO 流,在 iOS 12 中阻止了强制执行 SameSite 策略的 Cookie

Posted

技术标签:

【中文标题】对于涉及跨域请求的 SSO 流,在 iOS 12 中阻止了强制执行 SameSite 策略的 Cookie【英文标题】:Cookies with a SameSite policy enforced are blocked in iOS 12 for SSO flows involving cross-origin requests 【发布时间】:2019-01-29 15:30:00 【问题描述】:

总结:ios / OS 12 中的第三方登录中断!

我们有一个可以跨多个网站使用的通用登录名。这在 Windows、macOS 和 iOS 上的 Firefox、Chrome 和 Safari 中运行良好。但在 iOS 12 和 macOS 12 中,cookie 似乎不再适用于从 auth0 登录窗口到我们的登录 API。

它不仅在 Safari 中停止工作,而且在 iOS 12 上也在 Chrome 和 Firefox 中停止工作(它仍然在 Mac OS 12 上的 Chrome 中工作)。我怀疑这与智能跟踪预防 2.0 有关,但我很难找到许多技术细节。

我们的登录流程如下:

    用户单击登录,它将 window.location.href 设置为通用(不同)登录域上的登录 url。 这会调用 ChallengeAsync,它将用户发送到 auth0 域进行登录。 然后用户被发送回登录域,但此时来自 auth0 的 cookie 和控制器中设置的会话 cookie 丢失。

我在启动时使用以下内容:

    services.AddAuthentication(options => 
                    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                )
                .AddCookie(options =>
                
                    options.Cookie.Path = "/";
                    options.SlidingExpiration = false;
                )
                .AddOpenIdConnect("Auth0", options => 
                // Set the authority to your Auth0 domain
                options.Authority = $"https://Configuration["Auth0:Domain"]";

                // Configure the Auth0 Client ID and Client Secret
                options.ClientId = Configuration["Auth0:ClientId"];
                options.ClientSecret = Configuration["Auth0:ClientSecret"];

                // Set response type to code
                options.ResponseType = "code";

                // Configure the scope
                options.Scope.Clear();
                options.Scope.Add("openid");
                options.Scope.Add("profile");
                options.Scope.Add("email");
                options.Scope.Add("offline_access");
                options.CallbackPath = new PathString("/signin-auth0");
                options.ClaimsIssuer = "Auth0";
                options.SaveTokens = true;
                options.Events = new OpenIdConnectEvents
                
                    OnRemoteFailure = context => 
                        <not relevant error redirects>    
                    ,
                    OnRedirectToIdentityProvider = context =>
                    
                        context.ProtocolMessage.SetParameter("audience", $" Configuration["Auth0:ApiIdentifier"]");    
                        return Task.FromResult(0);
                    ,
                    OnRedirectToIdentityProviderForSignOut = (context) =>
                    
                        <not relevant logout handling>
                    
                ;
            );

在登录控制器中,我有一个登录操作,它只设置一个会话值并调用 ChallengeAsync 来打开 Auth0 登录:

await HttpContext.ChallengeAsync("Auth0", new AuthenticationProperties()  IsPersistent = true, ExpiresUtc = DateTime.UtcNow.AddMinutes(Global.MAX_LOGIN_DURATION_MINUTES), RedirectUri = returnUri );

“returnUri”参数是返回同一控制器的完整路径,但操作不同。当此操作被触发时,来自 auth0 登录(即https://ourcompany.eu.auth0.com)的 cookie 和我在登录操作中设置的会话数据在 iOS 12 中都丢失了。

我能否以适用于 iOS 12 的其他方式进行操作?感谢所有帮助。

【问题讨论】:

【参考方案1】:

我终于明白了。默认设置的 cookie 使用SameSiteMode.Lax。在 iOS 12 之前,这在任何地方都可以正常工作,现在需要将其设置为 SameSiteMode.None

这是我使用的修改让它再次工作:

.AddCookie(options =>
            
                options.Cookie.Path = "/";
                options.SlidingExpiration = false;
                options.Cookie.SameSite = SameSiteMode.None;
                options.Cookie.Expiration = TimeSpan.FromMinutes(Global.MAX_LOGIN_DURATION_MINUTES);
            )

【讨论】:

在仔细阅读 RFC6265 §5.3.7 和 §8.8.3 之后,这似乎是需要遍历涉及跨域请求的 SSO 流的任何 cookie 的预期解决方案。有关详细信息,请参阅WebKit issue。

以上是关于对于涉及跨域请求的 SSO 流,在 iOS 12 中阻止了强制执行 SameSite 策略的 Cookie的主要内容,如果未能解决你的问题,请参考以下文章

SSO单点登录跨域重定向跨域设置Cookie京东单点登录实例分析

单点登录认证原理及跨域cookie共享

iOS解决跨域问题

socket.io 跨域请求被阻止

vue跨域解决方法

一篇文章带你了解axios网络交互-Vue