介绍
如果我们项目使用了 Identity Server4的网站上使用HTTP时,用户将无法登录,因为Chrome在版本8x中进行了更改,当你在网站使用HTTP架构时,将会发生这种情况。其实主要是因为SameSite。
Google公司提出了一个不向后兼容的新标准草案。标准将默认模式更改为,并添加新条目以选择退出。 足以满足大多数应用程序 Cookie;但是,它会中断跨站点方案,如 OpenID 连接和 WS 联合身份验证登录。由于请求的流向不同,大多数 OAuth 登录不会受到影响。新参数会导致与实施先前草案标准的客户端(例如 iOS 12)的客户端的兼容性问题。Chrome 80 将包括更改。
如何解决它?
第一步AbpZero 项目应用 XXX.XXX.Web.Mvc 在项目中创建一个扩展类。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Microsoft.Extensions.DependencyInjection
{
public static class SameSiteCookiesServiceCollectionExtensions
{
/// <summary>
/// 设置SameSite属性,在ASPNET Core 3.1 项目中
/// </summary>
private const SameSiteMode Unspecified = (SameSiteMode)(-1);
/// <summary>
/// 配置cookie策略以正确设置SameSite属性
/// 适用于将未知值处理为“严格”的浏览器.确保您添加
/// <seealso cref="Microsoft.AspNetCore.CookiePolicy.CookiePolicyMiddleware" />
/// 发送任何Cookie之前进入管道!
/// </summary>
public static IServiceCollection ConfigureNonBreakingSameSiteCookies(this IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
return services;
}
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 = Unspecified;
}
}
}
/// <summary>
/// 检查是否已知UserAgent将未知值解释为Strict。
///<see cref="CookieOptions.SameSite" /> 属性设置为 <see cref="Unspecified" />.
/// </summary>
private static bool DisallowsSameSiteNone(string userAgent)
{
if (userAgent.Contains("Safari")
&& userAgent.Contains("Macintosh; Intel Mac OS X 10_14")
&& userAgent.Contains("Version/"))
{
return true;
}
// 判断 Chrome 50-69 版本, 这些默认为 SameSite=None
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
if (GetChromeVersion(userAgent) >= 80)
{
return true;
}
return false;
}
private static int GetChromeVersion(string userAgent)
{
try
{
return Convert.ToInt32(userAgent.Split("Chrome/")[1].Split('.')[0]);
}
catch (Exception)
{
return 0;
}
}
}
}
第二步
在Startup 类中 ConfigureServices 方法添加配置
services.ConfigureNonBreakingSameSiteCookies();
在Startup类中 Configure方法中添加配置
app.UseCookiePolicy();