如何在ASP.Net Core中配置Content Security Policy响应头
在ASP.NET Core中替代Global.asax设置Content Security Policy响应头
问题描述
我正在搭建首个ASP.NET Core网站,原网站基于Web Forms构建,因Web Forms支持不佳决定迁移至.NET Core。实际迁移难度远超预期,.NET Core移除了不少我这类.NET开发者此前依赖的功能,比如用来设置响应头(包括内容安全策略CSP)的Global.asax文件。
旧Global.asax中的代码如下:
protected void Application_PreSendRequestHeaders() { HttpContext.Current.Response.Headers.Add("Content-Security-Policy", "frame-src 'self' *.cloudflare.com *.abc30.com *.sinclairstoryline.com *.cnn.com *.foxnews.com *.twitch.tv *.cdninstagram.com *.fbcdn.net *.tiktok.com *.rumble.com *.rmbl.ws *.itemfix.com *.leakreality.com *.leakedreality.com *.reddit.com *.twitter.com *.dailymail.co.uk *.liveleak.com *.desmoinesregister.com *.kgw.com *.dailymotion.com *.bitchute.com *.metacafe.com *.vimeo.com *.nbcbayarea.com *.anvato.net *.abc30.com *.thv11.com *.youtube.com *.youtu.be *.google.com *.googlesyndication.com *.doubleclick.net *.jquery.net *.facebook.com *.bootstrapcdn.com *.cloudfront.net *.amazon.com *.googleapis.com *.shareaholic.net *.google-analytics.com *.viglink.com *.doubleclick.net *.tpc.googlesyndication.com *.cm.g.doubleclick.net *.pagead2.googlesyndication.com *.googleads.g.doubleclick.net *.accounts.google.com; upgrade-insecure-requests"); }
我需要在ASP.NET Core的Startup.cs或其他配置文件中实现全站响应头设置,目的是限制用户提交的视频嵌入仅能加载白名单站点的内容,防止恶意框架HTML页面。
解决方案
方法1:使用内置HeaderPolicy中间件(推荐)
ASP.NET Core 3.1及以上版本提供了内置的响应头策略中间件,可通过代码结构化配置CSP规则:
步骤1:在ConfigureServices中配置CSP策略
using Microsoft.AspNetCore.HeaderPolicy; public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); // 配置内容安全策略 services.AddHeaderPolicy(options => { options.AddContentSecurityPolicy(builder => { // 配置frame-src白名单 builder.AddFrameSrc() .Self() .From("*.cloudflare.com") .From("*.abc30.com") .From("*.sinclairstoryline.com") .From("*.cnn.com") .From("*.foxnews.com") .From("*.twitch.tv") .From("*.cdninstagram.com") .From("*.fbcdn.net") .From("*.tiktok.com") .From("*.rumble.com") .From("*.rmbl.ws") .From("*.itemfix.com") .From("*.leakreality.com") .From("*.leakedreality.com") .From("*.reddit.com") .From("*.twitter.com") .From("*.dailymail.co.uk") .From("*.liveleak.com") .From("*.desmoinesregister.com") .From("*.kgw.com") .From("*.dailymotion.com") .From("*.bitchute.com") .From("*.metacafe.com") .From("*.vimeo.com") .From("*.nbcbayarea.com") .From("*.anvato.net") .From("*.thv11.com") .From("*.youtube.com") .From("*.youtu.be") .From("*.google.com") .From("*.googlesyndication.com") .From("*.doubleclick.net") .From("*.jquery.net") .From("*.facebook.com") .From("*.bootstrapcdn.com") .From("*.cloudfront.net") .From("*.amazon.com") .From("*.googleapis.com") .From("*.shareaholic.net") .From("*.google-analytics.com") .From("*.viglink.com") .From("*.tpc.googlesyndication.com") .From("*.cm.g.doubleclick.net") .From("*.pagead2.googlesyndication.com") .From("*.googleads.g.doubleclick.net") .From("*.accounts.google.com"); // 启用升级不安全请求 builder.AddUpgradeInsecureRequests(); }); }); }
步骤2:在Configure中启用中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件(异常处理、静态文件等) // 注意:此中间件需放在路由中间件之前 app.UseHeaderPolicy(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
方法2:自定义中间件直接添加响应头
如果需要更灵活的控制逻辑,可以编写极简自定义中间件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件 // 自定义CSP响应头中间件,放在路由之前 app.Use(async (context, next) => { context.Response.Headers.Add("Content-Security-Policy", "frame-src 'self' *.cloudflare.com *.abc30.com *.sinclairstoryline.com *.cnn.com *.foxnews.com *.twitch.tv *.cdninstagram.com *.fbcdn.net *.tiktok.com *.rumble.com *.rmbl.ws *.itemfix.com *.leakreality.com *.leakedreality.com *.reddit.com *.twitter.com *.dailymail.co.uk *.liveleak.com *.desmoinesregister.com *.kgw.com *.dailymotion.com *.bitchute.com *.metacafe.com *.vimeo.com *.nbcbayarea.com *.anvato.net *.abc30.com *.thv11.com *.youtube.com *.youtu.be *.google.com *.googlesyndication.com *.doubleclick.net *.jquery.net *.facebook.com *.bootstrapcdn.com *.cloudfront.net *.amazon.com *.googleapis.com *.shareaholic.net *.google-analytics.com *.viglink.com *.doubleclick.net *.tpc.googlesyndication.com *.cm.g.doubleclick.net *.pagead2.googlesyndication.com *.googleads.g.doubleclick.net *.accounts.google.com; upgrade-insecure-requests"); await next(); }); app.UseRouting(); // 后续中间件... }
方法3:通过配置文件管理CSP规则(可选)
若想将规则与代码分离,可将CSP配置写入appsettings.json:
{ "ContentSecurityPolicy": { "FrameSrc": "'self' *.cloudflare.com *.abc30.com *.sinclairstoryline.com *.cnn.com *.foxnews.com *.twitch.tv *.cdninstagram.com *.fbcdn.net *.tiktok.com *.rumble.com *.rmbl.ws *.itemfix.com *.leakreality.com *.leakedreality.com *.reddit.com *.twitter.com *.dailymail.co.uk *.liveleak.com *.desmoinesregister.com *.kgw.com *.dailymotion.com *.bitchute.com *.metacafe.com *.vimeo.com *.nbcbayarea.com *.anvato.net *.abc30.com *.thv11.com *.youtube.com *.youtu.be *.google.com *.googlesyndication.com *.doubleclick.net *.jquery.net *.facebook.com *.bootstrapcdn.com *.cloudfront.net *.amazon.com *.googleapis.com *.shareaholic.net *.google-analytics.com *.viglink.com *.doubleclick.net *.tpc.googlesyndication.com *.cm.g.doubleclick.net *.pagead2.googlesyndication.com *.googleads.g.doubleclick.net *.accounts.google.com", "UpgradeInsecureRequests": true } }
然后在Startup中绑定配置并使用:
// 定义配置类 public class ContentSecurityPolicyConfig { public string FrameSrc { get; set; } public bool UpgradeInsecureRequests { get; set; } } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); // 绑定配置到类 var cspConfig = Configuration.GetSection("ContentSecurityPolicy").Get<ContentSecurityPolicyConfig>(); services.AddSingleton(cspConfig); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件 app.Use(async (context, next) => { var cspConfig = context.RequestServices.GetRequiredService<ContentSecurityPolicyConfig>(); var cspHeader = $"frame-src {cspConfig.FrameSrc};"; if (cspConfig.UpgradeInsecureRequests) { cspHeader += " upgrade-insecure-requests"; } context.Response.Headers.Add("Content-Security-Policy", cspHeader); await next(); }); // 后续中间件... }
补充建议
- 测试优先:可先使用
Content-Security-Policy-Report-Only头测试规则,仅在控制台报告违规,不阻止资源加载,确认无误后再切换到正式的Content-Security-Policy。 - 双重防护:除CSP头外,建议同时对用户提交的嵌入URL做白名单验证,避免绕过CSP的情况。
- 浏览器调试:使用浏览器开发者工具的「控制台」查看CSP违规提示,快速调整白名单规则。
内容的提问来源于stack exchange,提问作者PostAlmostAnything
相关产品推荐
相关产品推荐

