Net Core 3.1 在 iframe 中没有会话
Net Core 3.1 no session in iframe
当我们将我们的应用程序(net core 3.1,带有 vuejs 的单页应用程序)嵌入到另一个域页面上的 iframe 中时,对会话变量的请求始终为 null
很高兴知道:
进入页面时,首先要求用户填写一个名称,然后将其存储在会话中。
如果页面嵌入到同一域(我们的网站)上的页面上,则此机制工作正常,但当从另一个域上的 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 嵌入另一个站点的站点处于 cross-site 上下文中,这意味着它们的所有 cookie 都被浏览器视为 third-party,因此必须指定 SameSite=None
和Secure
在他们的属性中。
从 .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
header,以便为每个响应添加必要的 SameSite=None; Secure
。
将以下标记添加到 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,但最重要的是它可以正常工作。
当我们将我们的应用程序(net core 3.1,带有 vuejs 的单页应用程序)嵌入到另一个域页面上的 iframe 中时,对会话变量的请求始终为 null
很高兴知道: 进入页面时,首先要求用户填写一个名称,然后将其存储在会话中。
如果页面嵌入到同一域(我们的网站)上的页面上,则此机制工作正常,但当从另一个域上的 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 嵌入另一个站点的站点处于 cross-site 上下文中,这意味着它们的所有 cookie 都被浏览器视为 third-party,因此必须指定 SameSite=None
和Secure
在他们的属性中。
从 .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
header,以便为每个响应添加必要的 SameSite=None; Secure
。
将以下标记添加到 web.config
<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,但最重要的是它可以正常工作。