Chrome SameSite:Identity Server 4(代码流)+ Web API Core 3.1 + Angular 8
Chrome SameSite: Identity Server 4 (Code flow) + Web API Core 3.1 + Angular 8
我们的申请如下:
- Identity.Web (localhost:5555) - .Net Core 3.1:它有用于登录和密码重置的剃须刀页面。我们正在使用 Identity Server 4(代码流 - Oauth 2.0,OpenId)。
- Web.Api (localhost:4500) .Net Core 3.1: 基本具备资源API
- Angular 8(localhost:4200):使用open-id client认证访问资源API。
我们的应用程序在 Chrome SameSite Updates 之前可以完美运行。现在,每当我们输入用户名密码并登录(Identity.Web - localhost:5555)时,浏览器会重定向到(Angular 8 - localhost:4200),然后直接返回登录页面。
以前是有auth-callback,然后登录dashboard。
您可以在下面找到我们的配置:
Identity.Web (config.cs)
var redirectUris = new List<string> { frontendUrl + "/auth-callback", frontendUrl + "/silent-refresh.html" };
var allowedCorsOrigins = new List<string> { frontendUrl };
var postLogoutRedirectUris = new List<string> { frontendUrl + "/signout-callback-oidc" };
return new List<Client>
{
new Client
{
RequireConsent = false,
ClientId = "angular_spa",
ClientName = "Angular 4 Client",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
AllowedScopes = new List<string> {"openid", "profile", "api1"},
RedirectUris = redirectUris,
PostLogoutRedirectUris = postLogoutRedirectUris,
AllowedCorsOrigins = allowedCorsOrigins,
AllowAccessTokensViaBrowser = true,
}
};
Identity.Web (Startup.cs)
var settings = Configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>();
var mongoDbContext = new MongoDbContext(settings.ConnectionString, settings.DatabaseName);
services.AddIdentity<ApplicationUser, MongoIdentityRole>()
.AddMongoDbStores<ApplicationUser, MongoIdentityRole, Guid>(mongoDbContext)
.AddDefaultTokenProviders();
services.Configure<MongoSettings>(options =>
{
options.ConnectionString = Configuration.GetSection("MongoDbSettings:ConnectionString").Value;
options.DatabaseName = Configuration.GetSection("MongoDbSettings:DatabaseName").Value;
});
services.AddIdentityServer(options => { options.Events.RaiseSuccessEvents = true; })
.AddDeveloperSigningCredential()
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>()
.AddMongoRepository()
.AddClients()
.AddIdentityApiResources();
Web.Api (Startup.cs)
services.AddAuthentication()
.AddIdentityServerAuthentication("api1", options =>
{
options.Authority = Configuration.GetSection("IdentityServer:BaseUrl").Value;
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
options.TokenRetriever = (request) =>
{
string token = TokenRetrieval.FromAuthorizationHeader().Invoke(request);
if (string.IsNullOrEmpty(token))
{
token = TokenRetrieval.FromQueryString().Invoke(request);
}
return token;
};
});
注意: 一切都在 Firefox 中完美运行。我们阅读了 this 篇文章,并应用了其中的内容,但没有奏效。
Chrome 浏览器有一些 5555 端口的东西,改变你的 Identity.Web 端口,我希望它有效。
您将在 Google Chrome 中遇到以下控制台交战,并且您的身份服务器无法重定向到 Chrome 版本 80 的客户端应用程序。
与资源关联的 cookie 是使用 SameSite=None 设置的,但没有设置 Secure。它已被阻止,因为 Chrome 现在只提供标记为 SameSite=None 的 cookie,前提是它们也标记为安全。您可以在“应用程序”>“存储”>“Cookie”下的开发人员工具中查看 cookie,并在 https://www.chromestatus.com/feature/5633521622188032.
查看更多详细信息
要解决此问题,您需要进行下面提到的更改 link 以及下面提到的其他更改。
https://www.thinktecture.com/en/identity/samesite/prepare-your-identityserver/
注意:对于 .Net Core 2.2,设置 SameSite = (SameSiteMode)(-1),对于 .Net Core 3.0 或更高版本,设置 SameSite = SameSiteMode.Unspecified
此外,对于 Chrome 80 版本,添加此额外条件 -
if ( userAgent.Contains("Chrome/8"))
{
return true;
}
几个月来我一直在收到控制台消息,但 google 昨晚似乎已切换到此要求(针对英国)。
A cookie associated with a resource at http://localhost/ was set with `SameSite=None` but without `Secure`.
今天早上打开我的应用程序,然后砰的一声。和你一样的问题。如果我先退出 IDsrv,它在 Firefox 中工作。
如上所述,有一个解决方法,它适用于 .netCore 3.1。 link 对我来说不是那么清楚,所以我想我逐步完成修复以提供帮助。
打开您的身份服务器解决方案(在 Visual Studio 中)。
创建一个名为 Extensions 的新文件夹和一个名为“SameSiteCookiesServiceCollectionExtensions”的 class
粘贴上面 link 中的这段代码...
https://www.thinktecture.com/en/identity/samesite/prepare-your-identityserver/
但是,这还不足以让它发挥作用。在那个 class 中找到“DisallowsSameSiteNone”方法并将以下内容添加到底部(在关闭 return 语句之前)
var chromeVersion = GetChromeVersion(userAgent);
if (chromeVersion >= 80)
{
return true;
}
然后添加支持方法“chromeVersion”
private static int GetChromeVersion(string userAgent)
{
try
{
var subStr = Convert.ToInt32(userAgent.Split("Chrome/")[1].Split('.')[0]);
return subStr;
}
catch (Exception)
{
return 0;
}
}
您已完成此文件。保存它。
在您的 startup.cs 文件中(在项目的根目录中)在 configureServices 方法中添加此语句(我在 AddIdentityServer 选项之前添加了我的)。
services.ConfigureNonBreakingSameSiteCookies();
最后,在 Configure 方法中添加...
app.UseCookiePolicy();
app.UseAuthentication();
构建并再次尝试您的应用程序。希望对您有所帮助
我们的申请如下:
- Identity.Web (localhost:5555) - .Net Core 3.1:它有用于登录和密码重置的剃须刀页面。我们正在使用 Identity Server 4(代码流 - Oauth 2.0,OpenId)。
- Web.Api (localhost:4500) .Net Core 3.1: 基本具备资源API
- Angular 8(localhost:4200):使用open-id client认证访问资源API。
我们的应用程序在 Chrome SameSite Updates 之前可以完美运行。现在,每当我们输入用户名密码并登录(Identity.Web - localhost:5555)时,浏览器会重定向到(Angular 8 - localhost:4200),然后直接返回登录页面。
以前是有auth-callback,然后登录dashboard。
您可以在下面找到我们的配置:
Identity.Web (config.cs)
var redirectUris = new List<string> { frontendUrl + "/auth-callback", frontendUrl + "/silent-refresh.html" };
var allowedCorsOrigins = new List<string> { frontendUrl };
var postLogoutRedirectUris = new List<string> { frontendUrl + "/signout-callback-oidc" };
return new List<Client>
{
new Client
{
RequireConsent = false,
ClientId = "angular_spa",
ClientName = "Angular 4 Client",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
AllowedScopes = new List<string> {"openid", "profile", "api1"},
RedirectUris = redirectUris,
PostLogoutRedirectUris = postLogoutRedirectUris,
AllowedCorsOrigins = allowedCorsOrigins,
AllowAccessTokensViaBrowser = true,
}
};
Identity.Web (Startup.cs)
var settings = Configuration.GetSection(nameof(MongoDbSettings)).Get<MongoDbSettings>();
var mongoDbContext = new MongoDbContext(settings.ConnectionString, settings.DatabaseName);
services.AddIdentity<ApplicationUser, MongoIdentityRole>()
.AddMongoDbStores<ApplicationUser, MongoIdentityRole, Guid>(mongoDbContext)
.AddDefaultTokenProviders();
services.Configure<MongoSettings>(options =>
{
options.ConnectionString = Configuration.GetSection("MongoDbSettings:ConnectionString").Value;
options.DatabaseName = Configuration.GetSection("MongoDbSettings:DatabaseName").Value;
});
services.AddIdentityServer(options => { options.Events.RaiseSuccessEvents = true; })
.AddDeveloperSigningCredential()
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>()
.AddMongoRepository()
.AddClients()
.AddIdentityApiResources();
Web.Api (Startup.cs)
services.AddAuthentication()
.AddIdentityServerAuthentication("api1", options =>
{
options.Authority = Configuration.GetSection("IdentityServer:BaseUrl").Value;
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
options.TokenRetriever = (request) =>
{
string token = TokenRetrieval.FromAuthorizationHeader().Invoke(request);
if (string.IsNullOrEmpty(token))
{
token = TokenRetrieval.FromQueryString().Invoke(request);
}
return token;
};
});
注意: 一切都在 Firefox 中完美运行。我们阅读了 this 篇文章,并应用了其中的内容,但没有奏效。
Chrome 浏览器有一些 5555 端口的东西,改变你的 Identity.Web 端口,我希望它有效。
您将在 Google Chrome 中遇到以下控制台交战,并且您的身份服务器无法重定向到 Chrome 版本 80 的客户端应用程序。
与资源关联的 cookie 是使用 SameSite=None 设置的,但没有设置 Secure。它已被阻止,因为 Chrome 现在只提供标记为 SameSite=None 的 cookie,前提是它们也标记为安全。您可以在“应用程序”>“存储”>“Cookie”下的开发人员工具中查看 cookie,并在 https://www.chromestatus.com/feature/5633521622188032.
查看更多详细信息要解决此问题,您需要进行下面提到的更改 link 以及下面提到的其他更改。
https://www.thinktecture.com/en/identity/samesite/prepare-your-identityserver/
注意:对于 .Net Core 2.2,设置 SameSite = (SameSiteMode)(-1),对于 .Net Core 3.0 或更高版本,设置 SameSite = SameSiteMode.Unspecified
此外,对于 Chrome 80 版本,添加此额外条件 -
if ( userAgent.Contains("Chrome/8"))
{
return true;
}
几个月来我一直在收到控制台消息,但 google 昨晚似乎已切换到此要求(针对英国)。
A cookie associated with a resource at http://localhost/ was set with `SameSite=None` but without `Secure`.
今天早上打开我的应用程序,然后砰的一声。和你一样的问题。如果我先退出 IDsrv,它在 Firefox 中工作。
如上所述,有一个解决方法,它适用于 .netCore 3.1。 link 对我来说不是那么清楚,所以我想我逐步完成修复以提供帮助。
打开您的身份服务器解决方案(在 Visual Studio 中)。
创建一个名为 Extensions 的新文件夹和一个名为“SameSiteCookiesServiceCollectionExtensions”的 class
粘贴上面 link 中的这段代码... https://www.thinktecture.com/en/identity/samesite/prepare-your-identityserver/
但是,这还不足以让它发挥作用。在那个 class 中找到“DisallowsSameSiteNone”方法并将以下内容添加到底部(在关闭 return 语句之前)
var chromeVersion = GetChromeVersion(userAgent); if (chromeVersion >= 80) { return true; }
然后添加支持方法“chromeVersion”
private static int GetChromeVersion(string userAgent) { try { var subStr = Convert.ToInt32(userAgent.Split("Chrome/")[1].Split('.')[0]); return subStr; } catch (Exception) { return 0; } }
您已完成此文件。保存它。
在您的 startup.cs 文件中(在项目的根目录中)在 configureServices 方法中添加此语句(我在 AddIdentityServer 选项之前添加了我的)。
services.ConfigureNonBreakingSameSiteCookies();
最后,在 Configure 方法中添加...
app.UseCookiePolicy();
app.UseAuthentication();
构建并再次尝试您的应用程序。希望对您有所帮助