![](/img/trans.png)
[英]Configure ASP.Net Core Antiforgery to work with Angular SPA
[英]ASP.Net Core Antiforgery, Angular and IFRAMES
假设您有另一个网站想要在其中一个页面上的 IFRAME 中显示您的 Angular 应用程序。 如何配置 ASP.Net Core Antiforgery 才能正常工作?
我花了相当多的时间试图把它拼凑起来,所以这是我试图帮助其他人试图弄清楚如何让防伪令牌与 ASP.Net Core 6 和 Angular 应用程序一起显示在另一个网站上的 IFRAME 中的应用程序.
这假设您已经将ASP.Net Core Antiforgery 配置为与 Angular SPA 一起使用。
假设您有另一个网站想要在其中一个页面上的 IFRAME 中显示您的 Angular 应用程序。 您将遇到几个问题才能使其正常工作。 让我们一次解决一个。
默认情况下,当您调用service.GetAndStoreTokens(context)
时,Antiforgery 服务会将名为X-Frame-Options
的响应 header 设置为值SAMEORIGIN
。 根据MDN , “X-Frame-Options HTTP 响应 header 可用于指示是否应允许浏览器在<frame>
、 <iframe>
、 <embed>
或<object>
中呈现页面。可以使用它来避免点击劫持攻击,确保他们的内容不会嵌入到其他网站中。”
为了解决此问题,您需要在设置 Antiforgery 服务时关闭此行为:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
// suppress setting X-Frame-Options to SAMEORIGIN
options.SuppressXFrameOptionsHeader = true;
});
现在您的 web 页面显示在 IFRAME 内,但没有一个 POST 请求正常工作。 那是因为没有 cookies 被传递给它。
根据这篇优秀的文章, “这是一个相对较新的问题,直到最近 cookies 将通过跨站点请求发送。当谷歌浏览器更改SameSite cookie 属性的默认值时,这一切都改变了——引入新的默认值阻止这些 cookies 通过跨站点请求的行为。”
如果您观察网络流量,您会注意到应用程序入口点的 cookies 被标记为SameSite:Strict 。 这意味着只有当请求来自直接连接到您站点的客户端时,它们才会被发送。 它们不会被发送到 IFRAME,因此您的 Angular 应用程序无法读取它们并将其发送回 HEADER 请求的 HEADER 中。
要解决此问题,您需要修复两个cookies。 两者都需要更新为SameSite:None
(cookie 可以发送到任何站点)和Secure:true
(只能通过 HTTPS 传递),这将允许 cookie 流入 IFRAME。
首先,更新 Antiforgery 服务以修复默认 cookie 的属性:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
// suppress setting X-Frame-Options to SAMEORIGIN
options.SuppressXFrameOptionsHeader = true;
// allow cookie to be sent to IFRAME
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
然后更新发送到 Angular 应用程序的 cookie:
var app = builder.Build();
app.MapControllers();
var service = app.Services.GetRequiredService<IAntiforgery>();
app.Use(async (context, next) =>
{
var path = context.Request.Path;
if (path.Equals("/default.html", StringComparison.CurrentCultureIgnoreCase))
{
// generate .AspNetCore.Antiforgery authentication cookie
var tokenSet = service.GetAndStoreTokens(context);
var token = tokenSet.RequestToken;
// duplicate the .AspNetCore.Antiforgery authentication and create a cookie called XSRF-TOKEN
if (token != null)
{
context.Response.Cookies.Append("XSRF-TOKEN", token, new CookieOptions
{
Path = "/",
HttpOnly = false,
// allow cookie to be sent to IFRAME
SameSite = SameSiteMode.None,
Secure = true
});
}
}
await next(context);
});
此时,应用程序应在 IFRAME 中正常显示,并能够与 Web API 进行交互。 我希望这有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.