【问题标题】:Net Core 3.1 no session in iframeNet Core 3.1 iframe 中没有会话
【发布时间】:2020-09-02 09:37:44
【问题描述】:

当我们将我们的应用程序(net core 3.1,使用 vuejs 的单页应用程序)嵌入到另一个域的页面上的 iframe 中时,对会话变量的请求始终为空

很高兴知道: 进入页面时,首先要求用户填写一个名称,然后将其存储在会话中。

如果页面嵌入在同一域(我们的网站)上的页面上,则此机制可以正常工作,但是当从另一个域的 iframe 调用应用程序时,会话始终为空。

我阅读了一些关于“samesite cookie”的帖子,我猜这是配置和解决这个问题的方法吗? 我尝试了一些解决方案和示例,但没有发现任何区别。

这是来自 startup.cs 的代码。 久而久之……对不起……!

我已禁用所有同站点设置 需要哪些设置才能完成这项工作?

public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            //options.CheckConsentNeeded = context => false; // consent required
            //options.MinimumSameSitePolicy = SameSiteMode.None;
        });



        services.AddSession(opts =>
        {
            opts.IdleTimeout = TimeSpan.FromMinutes(60);
            //opts.Cookie.Name = "livestreamsupport.session";
            opts.Cookie.HttpOnly = true;

            opts.Cookie.IsEssential = true;
            //opts.Cookie.SameSite = SameSiteMode.None; 
            //opts.Cookie.SecurePolicy = CookieSecurePolicy.None;

        });


        //Add service for accessing current HttpContext
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddMemoryCache();
        //services.AddDistributedMemoryCache();

        services.AddAutoMapper(typeof(Startup));

        //add custom services
        services.AddTransient<ISurvey, Survey>();
        services.AddTransient<IQuestion, Question>();

        //services.AddDistributedMemoryCache();
        services.AddControllersWithViews().AddRazorRuntimeCompilation();
        services.AddControllers().AddNewtonsoftJson();

        services.AddDbContextPool<ApplicationContext>(
              options => options.UseMySql(Configuration.GetConnectionString("DefaultConnection"),
              mySqlOptions =>
              {
                  mySqlOptions.ServerVersion(new Version(5, 7, 17), ServerType.MySql)
                  .EnableRetryOnFailure(
                  maxRetryCount: 10,
                  maxRetryDelay: TimeSpan.FromSeconds(30),
                  errorNumbersToAdd: null);
              })
        );

        services.AddDefaultIdentity<User>()
            .AddRoles<IdentityRole>()
            .AddRoleManager<RoleManager<IdentityRole>>()
            .AddEntityFrameworkStores<ApplicationContext>();


        services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = true;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;

            // User settings
            options.User.RequireUniqueEmail = true;
        });

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
            options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
            options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
        });

        //services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
        //{
        //    //options.LoginPath = new PathString("/login");
        //    options.Cookie.SameSite = SameSiteMode.None;
        //    options.Cookie.SecurePolicy = CookieSecurePolicy.None;
        //});

        services.AddAuthorization();

        //services.ConfigureApplicationCookie(options => {
        //    options.Cookie.SameSite = SameSiteMode.None;
        //    //options.LoginPath = "/Account/Login";
        //    //options.LogoutPath = "/Account/Logout";
        //    //options.AccessDeniedPath = "/Account/Login";
        //});

        //services.AddAntiforgery(opts => {
        //    opts.Cookie.SameSite = SameSiteMode.None;
        //});

        services.AddSignalR();
    }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseRouting();

        app.UseHttpsRedirection();

        //app.UseHttpsRedirection();
        app.UseDefaultFiles();

        var supportedCultures = new[] { "en-US", "en" };
        var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
            .AddSupportedCultures(supportedCultures)
            .AddSupportedUICultures(supportedCultures);

        app.UseRequestLocalization(localizationOptions);

        app.UseStaticFiles();

        //app.UseCookiePolicy(new CookiePolicyOptions
        //{
        //    MinimumSameSitePolicy = SameSiteMode.None
        //});

        app.UseAuthentication();
        app.UseAuthorization();

        //app.UseCors();

        app.UseSession();

        app.UseEndpoints(endpoints =>
        {

            endpoints.MapRazorPages();
            endpoints.MapHub<ChatHub>("/chatHub");
            endpoints.MapControllers();

            //zorg ervoor dat geen gebruik kan worden gemaakt van de default identity routes
            endpoints.MapGet("/Identity/Account/Login",context => Task.Factory.StartNew(() => context.Response.Redirect("/Account/Login", true, true)));

            //endpoints.MapDefaultControllerRoute();
            endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");

            endpoints.MapControllerRoute(
                    name: "api",
                    pattern: "api/{controller}/{action}/{id?}",
                    defaults: new { controller = "survey", action = "getpollresults" });


        });

        //maak de httpcontext beschikbaar in de applicatie
        AppHttpContext.Services = app.ApplicationServices;
    }

【问题讨论】:

    标签: iframe .net-core samesite


    【解决方案1】:

    通过 iframe 嵌入另一个站点的站点处于跨站点上下文中,这意味着它们的所有 cookie 都被浏览器视为第三方,因此必须在其属性中指定 SameSite=NoneSecure

    从 .net 4.72 开始支持此功能:https://docs.microsoft.com/en-us/aspnet/samesite/system-web-samesite

    如果您无法更新 .net 实现,您可能可以按照此处的说明进行操作:https://github.com/GoogleChromeLabs/samesite-examples/blob/master/aspnet.md 进行修补。

    或者,您也可以使用代理,例如您的网络服务器,更改出站响应中的 set-cookie 标头,以便为每个响应添加必要的 SameSite=None; Secure

    【讨论】:

    • 感谢您的回复。信息很详细,我很难理解,抱歉。我已经在 IIS 中尝试了出站规则方法,我们可以访问(虚拟)服务器。不幸的是,这并没有什么不同。会话仍然丢失。 (在页面刷新时过期)。我们想要的只是在 iframe 中显示一个已经很好工作的网页(当不在 iframe 中时)。它可能是一个(简单的)设置,但我不知道是哪一个!
    • 现在可以了。将以下标签添加到 web.config 使 iframe 中的会话正常工作。
    【解决方案2】:

    将以下标签添加到 web.config 标签使 iframe 中的会话工作。 SameSite=None 可以解决问题。

    <rewrite>
    <outboundRules>
      <clear />
      <rule name="Add SameSite" preCondition="No SameSite">
        <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
        <action type="Rewrite" value="{R:0}; SameSite=None;Secure=true" />
      </rule>
      <preConditions>
        <preCondition name="No SameSite">
                            <add input="{RESPONSE_Set_Cookie}" pattern="." />
                            <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=None;Secure=true" negate="true" />
        </preCondition>
      </preConditions>
    </outboundRules>
    

    我希望我能在 net core 3.1 中找到正确的设置。应用程序而不是在网络服务器上配置 IIS,但最重要的是它可以工作。

    【讨论】:

      猜你喜欢
      • 2021-04-26
      • 2021-01-20
      • 2021-02-24
      • 1970-01-01
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      相关资源
      最近更新 更多