Iframe不遵守登录cookie

7
我有一个非常奇怪的问题,我已经试图调试了一周多。我对问题的根源毫无头绪,希望这里的某个人之前遇到过同样的问题,并能给我一个解决办法。
我正在开发一款asp .net core 2.0应用程序。独立运行时很好用。
以下是应用程序的主控制器的操作流程:
1. 需要身份验证。
2. 登录Identity Server 4。(混合授权类型)
3. 返回应用程序,获取数据并展示结果。
现在,当我尝试将此应用程序作为插件添加到主应用程序中时,它就无法正常工作。实际上,它会进入循环。插件以iFrame的形式显示在主应用程序中。
<iframe src="https://XXXXX" sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox" width="500" height="500"></iframe>

观察日志。我可以看到它被转发到身份验证服务器,记录返回到插件界面,我可以看到它。

OnSignedIn: IsAuthenticated = True

我看到插件有一个访问令牌。然后循环开始了。它返回到身份服务器再次请求访问,整个过程无休止地继续。
我发现独立运行和作为插件运行之间的不同之处在于日志中缺少这一行。
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[10]
AuthenticationScheme: Cookies signed in.

我还可以在请求头中看到,身份验证服务器返回了cookie标头并告诉它进行setcookie操作,但是它从未被设置。

为什么在iframe中无法设置cookie?

我尝试过的方法:

 options.Cookie.SameSite = SameSiteMode.Lax;
 options.Cookie.SecurePolicy = CookieSecurePolicy.None;

内容安全策略头包括身份服务器、插件站点和主要的网站应用程序。

为什么cookie没有设置?

插件认证代码。

 services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";


            })
            .AddCookie("Cookies", options =>
            {
                options.Cookie.SameSite = SameSiteMode.Lax;
                options.Cookie.SecurePolicy = CookieSecurePolicy.None;
                options.SessionStore = new MemoryCacheTicketStore();                   
            })
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";

                options.Authority = Configuration["ServiceSettings:IdentityServerEndpoint"];
                options.RequireHttpsMetadata = false;

                options.ClientId = Configuration["ServiceSettings:ClientId"];
                options.ClientSecret = Configuration["ServiceSettings:secret"];
                options.ResponseType = "code id_token";

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("profile");
                options.Scope.Add("testapi");

            });
    }

标头

 app.Use(async (ctx, next) =>
        {
            ctx.Response.Headers.Add("Content-Security-Policy", Configuration["DefaultApplicationSettings:ContentSecurityPolicy"]);

            await next();
        });

设置

 "DefaultApplicationSettings": {
"ContentSecurityPolicy": "default-src 'self' plugin webapp; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com/ webapp; font-src 'self' https://fonts.gstatic.com/ webapp; frame-ancestors 'self' webapp"  },

由于公司隐私原因,网址已更改。


我已经在Chrome和Edge中尝试过了。 - Linda Lawton - DaImTo
Firefox提示[身份服务器登录网址]不允许跨域框架,正在尝试寻找使用其他浏览器的同事进行测试。 - Linda Lawton - DaImTo
我已经为您添加了标题,但由于需要更改URL,不确定它有多大用处。 - Linda Lawton - DaImTo
这不是JavaScript或Ajax,我在identityserver上没有它。当作为插件或独立运行时,浏览器中也没有出现Cors错误。 - Linda Lawton - DaImTo
1个回答

17

在大量搜索后,我的一位同事在身份验证服务器4源代码中找到了一条评论

IdentityServerBuilderExtensions.cs

 // we need to disable to allow iframe for authorize requests
 cookie.Cookie.SameSite = AspNetCore.Http.SameSiteMode.None;

我一改变的瞬间

options.Cookie.SameSite = SameSiteMode.Lax;

options.Cookie.SameSite = SameSiteMode.None;

它起作用了。

指示浏览器是否仅允许将Cookie附加到同站点请求(SameSiteMode.Strict),还是同时允许跨站点请求使用安全的HTTP方法和同站点请求(SameSiteMode.Lax)。 当设置为SameSiteMode.None时,不会设置Cookie头值。请注意,Cookie策略中间件可能会覆盖您提供的值。为了支持OAuth身份验证,默认值为SameSiteMode.Lax。有关更多信息,请参见“由于SameSite cookie策略而破坏的OAuth身份验证”。

为什么它能够工作我仍不清楚,但它确实起作用了。


2
这是有效的,因为将SaneSite设置为none时,浏览器会在从iframe发出的请求中发送登录cookie。如果它是lax,则仅在重定向到顶级导航URL时才发送cookie。这是一种用于缓解CSRF攻击的机制。 - tha4
你节省了我的时间,@daimto。谢谢。 - Agni
这难道不会为 CSRF 开放攻击面吗? - beppe9000
1
它对我也起作用了,谢谢。我正在使用 .Net Core 3 Web 应用程序。 我将那段代码添加到 StratUp.cs 中:我添加了身份验证 cookie。 - Amir-ranjbar
1
它对我也起作用了,我正在使用.NET 5和带有SAML的Okta。在我的启动中,当我添加Saml时,我进行了调整: services.AddSaml2();services.AddSaml2(cookieSameSite: Microsoft.AspNetCore.Http.SameSiteMode.None); - Tim Burris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接