注意
此版本不是本文的最新版本。 有关当前版本,请参阅 本文的 .NET 10 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 有关当前版本,请参阅本文的 .NET 9 版本。
本文介绍如何将内容安全策略(CSP)与 ASP.NET 核心 Blazor 应用配合使用,以帮助防范某些类型的恶意攻击,例如 跨站点脚本(XSS) 和 点击劫持 攻击。 XSS 是一个安全漏洞,其中网络攻击者将一个或多个恶意客户端脚本放入应用的呈现内容中。 在点击劫持攻击中,用户被欺骗与包含您的应用的诱饵网站进行交互。
CSP 通过通知浏览器哪些资源是有效的,帮助防范这些类型的攻击。
- 已加载内容的源,包括脚本、样式表、图像和插件。
- 页面执行的操作,指定允许的表单 URL 目标。
- 当您的应用程序可以通过
<frame>、<iframe>、<object>或<embed>标记嵌入到其他网站中时。
建议在实现 CSP 时读取以下 MDN 资源:
要将 CSP 应用于应用,开发人员会在一个或多个 标头或 Content-Security-Policy 标记中指定多个 CSP 内容安全指令。 有关在启动时将 CSP 应用于 C# 代码中的应用的指导,请参阅本文后面的 ASP.NET Core Blazor 启动和“指令”frame-ancestors部分。
加载页面时,浏览器会对策略进行评估。 浏览器将检查页面的源并确定它们是否满足内容安全指令的要求。 如果资源不符合策略指令,浏览器不会加载资源。 例如,请考虑不允许第三方脚本的策略。 当某个页面的 <script> 属性中包含带有第三方来源的 src 标记时,浏览器将阻止加载该脚本。
大多数新式桌面和移动浏览器(包括 Chrome、Microsoft Edge、Firefox、Opera 和 Safari)都支持 CSP。 建议将 CSP 用于 Blazor 应用。
警告
实现 CSP 可最大程度地降低某些安全威胁的风险,并不能保证应用完全安全免受 XSS 和点击劫持攻击。 用户代理(通常为浏览器)可能允许用户通过用户首选项、bookmarklet、浏览器扩展、对用户代理的第三方添加等机制来修改或绕过策略强制实施。 此外,CSP 只专注于修正一部分攻击,并非所有可能危及安全性的攻击,例如 SQL 注入、跨站点请求伪造(CSRF)、安全配置错误和拒绝服务(DoS)攻击。
策略指令
以下指令和源通常用于 Blazor 应用。 按需添加其他指令和源。 本文的 “应用策略 ”部分使用了以下指令,其中提供了应用的安全策略 Blazor 示例:
-
base-uri:限制页面的<base>标记的 URL。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
default-src:指示未被策略显式指定的源指令的回退。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
img-src:指示图像的有效源。- 指定
data:,以允许从data:URL 加载图像。 - 指定
https:,以允许从 HTTPS 终结点加载图像。
- 指定
-
object-src:指示<object>、<embed>和<applet>标记的有效源。 指定none以阻止所有 URL 源。 -
script-src:指示脚本的有效源。- 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 在客户端 Blazor 应用中:
- 指定
wasm-unsafe-eval以允许客户端 Blazor Mono 运行时正常运行。 - 指定任何其他哈希值以允许加载所需的非框架脚本。 例如,使用哈希
unsafe-hashes指定sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=以允许组件中NavMenu导航切换器的内联 JavaScript。
- 指定
- 在服务器端 Blazor 应用中,指定哈希以允许加载所需的脚本。
- 指定
-
style-src:指示样式表来源的有效性。- 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 如果应用使用嵌入式样式,则指定
unsafe-inline以允许使用嵌入式样式。
- 指定
-
connect-src:限制可以使用脚本接口加载的 URL。 指定方案源http:ws:(WebSocket 协议)和wss:(WebSocket Secure 协议)。 - upgrade-insecure-requests:指示应通过 HTTPS 安全地获取来自不安全 (HTTP) 源的内容 URL。
-
base-uri:限制页面的<base>标记的 URL。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
default-src:指示未被策略显式指定的源指令的回退。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
img-src:指示图像的有效源。- 指定
data:,以允许从data:URL 加载图像。 - 指定
https:,以允许从 HTTPS 终结点加载图像。
- 指定
-
object-src:指示<object>、<embed>和<applet>标记的有效源。 指定none以阻止所有 URL 源。 -
script-src:指示脚本的有效源。- 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 在客户端 Blazor 应用中:
- 指定
unsafe-eval以允许客户端 Blazor Mono 运行时正常运行。 - 指定任何其他哈希值以允许加载所需的非框架脚本。
- 指定
- 在服务器端 Blazor 应用中,指定哈希以允许加载所需的脚本。
- 指定
-
style-src:指示样式表来源的有效性。- 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 如果应用使用嵌入式样式,则指定
unsafe-inline以允许使用嵌入式样式。
- 指定
-
connect-src:限制可以使用脚本接口加载的 URL。 指定方案源http:ws:(WebSocket 协议)和wss:(WebSocket Secure 协议)。 -
upgrade-insecure-requests:指示应通过 HTTPS 安全地获取来自不安全 (HTTP) 源的内容 URL。
-
base-uri:限制页面的<base>标记的 URL。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
default-src:指示未被策略显式指定的源指令的回退。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
img-src:指示图像的有效源。- 指定
data:,以允许从data:URL 加载图像。 - 指定
https:,以允许从 HTTPS 终结点加载图像。
- 指定
-
object-src:指示<object>、<embed>和<applet>标记的有效源。 指定none以阻止所有 URL 源。 -
script-src:指示脚本的有效源。- 指定用于启动脚本的
https://stackpath.bootstrapcdn.com/主机源。 - 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 在客户端 Blazor 应用中:
- 指定
unsafe-eval以允许客户端 Blazor Mono 运行时正常运行。 - 指定任何其他哈希值以允许加载所需的非框架脚本。
- 指定
- 在服务器端 Blazor 应用中,指定哈希以允许加载所需的脚本。
- 指定用于启动脚本的
-
style-src:指示样式表来源的有效性。- 指定用于启动样式表的
https://stackpath.bootstrapcdn.com/主机源。 - 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 指定
unsafe-inline,以允许使用内联样式。
- 指定用于启动样式表的
-
connect-src:限制可以使用脚本接口加载的 URL。 指定方案源http:ws:(WebSocket 协议)和wss:(WebSocket Secure 协议)。 -
upgrade-insecure-requests:指示应通过 HTTPS 安全地获取来自不安全 (HTTP) 源的内容 URL。
-
base-uri:限制页面的<base>标记的 URL。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
default-src:指示未被策略显式指定的源指令的回退。 指定self,以指示应用的来源(包括方案和端口号)是有效源。 -
img-src:指示图像的有效源。- 指定
data:,以允许从data:URL 加载图像。 - 指定
https:,以允许从 HTTPS 终结点加载图像。
- 指定
-
object-src:指示<object>、<embed>和<applet>标记的有效源。 指定none以阻止所有 URL 源。 -
script-src:指示脚本的有效源。- 指定用于启动脚本的
https://stackpath.bootstrapcdn.com/主机源。 - 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 在客户端 Blazor 应用中:
- 执行哈希以允许加载所需的脚本。
- 指定
unsafe-eval,以使用eval()以及通过字符串创建代码的方法。
- 在服务器端 Blazor 应用中,指定哈希以允许加载所需的脚本。
- 指定用于启动脚本的
-
style-src:指示样式表来源的有效性。- 指定用于启动样式表的
https://stackpath.bootstrapcdn.com/主机源。 - 指定
self,以指示应用的来源(包括方案和端口号)是有效源。 - 指定
unsafe-inline,以允许使用内联样式。 UI 需要内联声明,以便在初始请求后重新连接客户端和服务器。 在将来的版本中,可能会删除内联样式,以便不再需要unsafe-inline。
- 指定用于启动样式表的
-
connect-src:限制可以使用脚本接口加载的 URL。 指定方案源http:ws:(WebSocket 协议)和wss:(WebSocket Secure 协议)。 -
upgrade-insecure-requests:指示应通过 HTTPS 安全地获取来自不安全 (HTTP) 源的内容 URL。
除 Microsoft Internet Explorer 外的所有浏览器都支持上述指令。
获取其他内联脚本的 SHA 哈希:
- 应用应用策略部分中所示的 CSP。
- 在本地运行应用时访问浏览器的开发人员工具控制台。 当存在 CSP 标头或
meta标记时,浏览器将为遭到阻止的脚本计算和显示哈希。 - 将浏览器提供的哈希复制到
script-src源。 在每个哈希两边使用单引号。
有关内容安全策略级别 2 浏览器的支持矩阵,请参阅我可以使用:内容安全策略级别 2。
应用策略
可以通过以下方法应用 CSP:
- 由主机(例如 IIS)或应用颁发的响应标头(请参阅 启动时的 C# 代码中的 Control 标头)。
- 标记
<meta>。 本文仅演示<meta>标记方法。
若要使用 <meta> 标记应用策略,请执行以下步骤:
- 将
http-equiv属性的值设置为Content-Security-Policy。 - 将指令置于
content属性值中。 使用分号 (;) 分隔指令。 根据 内容安全策略级别 3 规范,不需要策略字符串的最后一个指令的结束分号。 - 将
<meta>标记放在<head>开始标记内的内容的起始处。 在解析 CSP 标记时,将对策略进行评估和强制执行,因此该策略应出现在<head>标记的顶部,以确保在所有<script>和<link>标记上强制执行。
以下各部分介绍示例策略。 对于 Blazor 的每个版本,本文都对这些示例进行了版本控制。 要使用适用于你的版本的版本,请在此网页上使用“版本”下拉选择器选择文档版本。
frame-ancestors 指令
该frame-ancestors指令指定可以嵌入包含<frame>、<iframe>、<object>或<embed>标签的页面的有效父级。
frame-ancestors指令无法通过基于标签的<meta> CSP 应用。 指令必须通过响应标头来应用。 服务器主机可以添加 CSP 响应标头,或者应用 C# 代码可以使用指令添加或更新 CSP frame-ancestors 。
Blazor Web Apps(.NET 8 或更高版本)自动包含响应头,将值设置为 'self':
Content-Security-Policy: frame-ancestors 'self'
若要将默认值更改为更严格的值'none'并阻止所有父级嵌入应用,请在ContentSecurityFrameAncestorsPolicy文件中调用AddInteractiveServerRenderMode时设置Program选项。 仅当启用ConfigureWebSocketAcceptContext WebSocket 压缩(设置为默认值,这是 Blazor 应用的默认值)时,以下才生效。
.AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = "'none'")
在 Blazor Server 应用中,默认 frame-ancestors 指令不会添加到响应标头集合中。 可以在请求处理管道中使用 中间件 手动添加 CSP 标头:
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Content-Security-Policy", "frame-ancestors 'none'");
await next();
});
警告
避免将 frame-ancestors 指令值设置为 'null' 启用 WebSocket 压缩(压缩为默认值),因为它使应用容易受到恶意脚本注入和点击劫持攻击。
有关详细信息,请参阅 CSP:框架祖先 (frame-ancestors)(MDN 文档)。
服务器端 Blazor 应用
以下示例是进一步开发的起点。 在内容顶部<head>,应用策略指令部分中所述的指令以及应用规范所需的任何其他指令。
对于 Blazor Web App 或 Blazor Server 应用程序:
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'wasm-unsafe-eval' 'unsafe-hashes'
'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=';
style-src https:;
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests;" />
在Blazor Web App组件中包含一个内联onclick JavaScript 事件处理程序,该事件处理程序需要进行以下任一更改:
使用
script-src关键字向unsafe-hashes指令添加哈希:'unsafe-hashes' 'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0='有关详细信息,请参阅 CSP:script-src:不安全内联脚本(MDN 文档)。
将内联 JavaScript 事件处理程序移动到允许由策略加载的 JavaScript 文件或模块。
Blazor Web App此外,内容中ImportMap还有一个<head>呈现内联导入映射<script>标记的组件。 若要修改策略以允许导入映射加载,请参阅 解决子资源完整性(SRI)或加密 nonce 部分的 CSP 冲突 。
对于 Blazor Server 应用:
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self';
style-src 'self';
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests">
对于 Blazor Server 应用:
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' https://stackpath.bootstrapcdn.com/;
style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests">
对于 Blazor Server 应用:
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' https://stackpath.bootstrapcdn.com/
'sha256-34WLX60Tw3aG6hylk0plKbZZFXCuepeQ6Hu7OqRf8PI=';
style-src 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests">
注意
前面的 SHA256 哈希用于演示目的。 可能需要计算 CSP 的新哈希。
添加应用所需的其他 script-src 和 style-src 哈希。 在开发期间,使用联机工具或浏览器开发人员工具来计算哈希。 例如,以下浏览器工具控制台错误为策略未涵盖的必需脚本报告哈希:
拒绝执行内联脚本,因为它违反以下内容安全策略指令:“...”。 若要启用内联执行,需要使用“unsafe-inline”关键字、哈希(“sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=”)或 nonce(“nonce-...”)。
与错误关联的特定脚本显示在错误旁边的控制台中。
有关在启动时将 CSP 应用于使用 C# 代码的应用的指南,请参阅 ASP.NET Core Blazor 启动。
客户端 Blazor 应用
以下示例是进一步开发的起点。 在 <head> 内容中,应用“策略指令”部分中描述的指令:
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'wasm-unsafe-eval';
style-src 'self';
connect-src 'none';
upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'unsafe-eval';
style-src 'self';
connect-src 'none';
upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'unsafe-eval'
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=';
style-src 'self';
connect-src 'none';
upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'unsafe-eval' https://stackpath.bootstrapcdn.com/
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=';
style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'unsafe-eval' https://stackpath.bootstrapcdn.com/
'sha256-v8ZC9OgMhcnEQ/Me77/R9TlJfzOBqrMTW8e1KuqLaqc='
'sha256-If//FtbPc03afjLezvWHnC3Nbu4fDM04IIzkPaf3pH0='
'sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=';
style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com/;
upgrade-insecure-requests">
添加应用所需的其他 script-src 和 style-src 哈希。 在开发期间,使用联机工具或浏览器开发人员工具来计算哈希。 例如,以下浏览器工具控制台错误为策略未涵盖的必需脚本报告哈希:
拒绝执行内联脚本,因为它违反以下内容安全策略指令:“...”。 若要启用内联执行,需要使用“unsafe-inline”关键字、哈希(“sha256-v8v3RKRPmN4odZ1CWM5gw80QKPCCWMcpNeOmimNL2AA=”)或 nonce(“nonce-...”)。
与错误关联的特定脚本显示在错误旁边的控制台中。
通过子资源完整性(SRI)或加密随机数解决CSP违规问题
解决 CSP 冲突的两种方法如下两部分所述:
采用子资源完整性(SRI)
子资源完整性(SRI)使浏览器能够确认提取的资源不会在传输中被篡改。 在资源上提供的加密哈希必须与浏览器为获取的资源计算的哈希以及 CSP 中列出的哈希相匹配。 可以在Can I use? Subresource Integrity网站上评估浏览器兼容性。
在下面的示例中,使用第三方工具计算 Blazor Server 应用的完整性,并为脚本 (Blazor) 和 CSP 指定 blazor.server.js。 此 Blazor 脚本在此方案中不会动态更改,并且具有稳定的 SHA 哈希,因此可以硬编码 integrity 特性的值。
警告
在从不同源加载且未使用crossorigin的子资源上设置属性。 如果应用的源与子资源加载的位置不同,则需要一个Access-Control-Allow-Origin标头,该标头允许与请求源共享资源,否则crossorigin属性必须应用于应用中的子资源标记。 否则,浏览器为子资源采用“失败打开”策略,这意味着加载子资源而不检查其完整性。
以下示例中,未将 crossorigin 属性添加到 Blazor<script> 标记中,因为 Blazor 脚本是从应用程序的源地址加载的。
有关详细信息,请参阅跨域资源共享和子资源完整性(MDN 文档)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'sha256-FyuamsHhg0nWZUnu/f5qrt2DlL1XKt5AX+cgRhtxtfg=';
style-src https:;
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests;" />
...
</head>
<body>
...
<script src="_framework/blazor.server.js"
integrity="sha256-FyuamsHhg0nWZUnu/f5qrt2DlL1XKt5AX+cgRhtxtfg="></script>
</body>
</html>
在以下示例中( Blazor Web App .NET 8 或更高版本),计算 ImportMap 组件(.NET 9 或更高版本)的完整性。 每次为指纹资产生成页面时,ImportMap组件ImportMap都会为每个应用请求计算完整性值,因为组件每次生成页面时都会呈现唯一的内容。
从 ImportMap 组件呈现的导入映射由应用在其源处生成,所以 crossorigin 属性 不包含在 ImportMap 标记中。 有关详细信息,请参阅 MDN CSP 指南:哈希和子资源完整性(MDN 文档)。
@using System.Security.Cryptography
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'wasm-unsafe-eval' 'unsafe-hashes' '@integrity'
'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=';
style-src https:;
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests;" />
...
<ImportMap integrity="@integrity" />
...
</head>
...
</html>
@code {
private string? integrity;
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
var metadata = HttpContext?.GetEndpoint()?.Metadata
.GetOrderedMetadata<ImportMapDefinition>();
var utf8 = new System.Text.UTF8Encoding();
var metadataBytes = utf8.GetBytes(
metadata?.FirstOrDefault<ImportMapDefinition>()?.ToString()
.ReplaceLineEndings("\n") ?? string.Empty);
integrity =
$"sha256-{Convert.ToBase64String(SHA256.HashData(metadataBytes))}";
}
}
在 .NET 6 之前,请使用 .Replace("\r\n", "\n") 而不是调用 ReplaceLineEndings 上述代码。
注意
如果必须在ImportMap组件的呈现<script>元素上展开其他属性,则可以将所有属性的字典传递给ImportMap组件的AdditionalAttributes属性。 属性名称-值对 integrity 和其他附加传递的属性一起传递到字典中。
采用加密随机数 (nonce)
加密 nonce(一次使用的数字)使浏览器能够确认提取的资源不会在传输中被篡改。 CSP 中提供的一次性加密 nonce 必须与资源上指示的 nonce 匹配。 浏览器兼容性可以在Can I use? Nonce进行评估。
在以下示例中,对于 Blazor Web App(.NET 8 或更高版本),每次应用程序加载时,都会为 ImportMap 组件(.NET 9 或更高版本)生成一个具有唯一值的 nonce。
有关详细信息,请参阅 MDN CSP 指南:Nonces 和 CSP:script-src:Unsafe inline script (MDN 文档)。
@using System.Security.Cryptography
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
default-src 'self';
img-src data: https:;
object-src 'none';
script-src 'self' 'wasm-unsafe-eval' 'unsafe-hashes' 'nonce-@nonce'
'sha256-qnHnQs7NjQNHHNYv/I9cW+I62HzDJjbnyS/OFzqlix0=';
style-src https:;
connect-src 'self' http: ws: wss:;
upgrade-insecure-requests;" />
...
<ImportMap nonce="@nonce" />
...
</head>
...
</html>
@code {
private string? nonce;
protected override void OnInitialized()
{
using (var rng = RandomNumberGenerator.Create())
{
var nonceBytes = new byte[32];
rng.GetBytes(nonceBytes);
nonce = Convert.ToBase64String(nonceBytes);
}
}
}
注意
如果必须在ImportMap组件的呈现<script>元素上展开其他属性,则可以将所有属性的字典传递给ImportMap组件的AdditionalAttributes属性。 nonce 名称/值对在字典中传递,其余附加传递的属性。
在非 Development 环境中应用 CSP
将 CSP 应用于 Blazor 应用的 <head> 内容时,它会干扰 Development 环境中的本地测试。 例如,无法加载浏览器链接和浏览器刷新脚本。 以下示例演示如何在非 <meta> 环境中应用 CSP 的 Development 标记。
注意
本节中的示例不显示 CSP 的完整 <meta> 标记。 完整 <meta> 标记可以在本文前面的应用策略一节的小节中找到。
有三种常规方法可用:
- 通过
App组件应用 CSP,该组件将 CSP 应用于应用的所有布局。 - 如果需要将 CSP 应用到应用的不同区域(例如,仅用于管理页面的自定义 CSP),请使用
<HeadContent>标记按布局应用 CSP。 为了完全有效,每个应用布局文件都必须采用该方法。 - 托管服务或服务器可以通过添加应用的传出响应的
Content-Security-Policy标头来提供 CSP。 由于该方法因托管服务或服务器而异,因此不在下面的示例中进行讨论。 如果想要采用该方法,请参阅托管服务提供程序或服务器的文档。
Blazor Web App 方法
在 App 组件 (Components/App.razor) 中,注入 IHostEnvironment:
@inject IHostEnvironment Env
在 App 组件的 <head> 内容中,当不在 Development 环境中时应用 CSP:
@if (!Env.IsDevelopment())
{
<meta ...>
}
或者,在 Components/Layout 文件夹中按布局应用 CSP,如以下示例所示。 确保每个布局都指定一个 CSP。
@inject IHostEnvironment Env
@if (!Env.IsDevelopment())
{
<HeadContent>
<meta ...>
</HeadContent>
}
Blazor WebAssembly 应用方法
在 App 组件 (App.razor) 中,注入 IWebAssemblyHostEnvironment:
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IWebAssemblyHostEnvironment Env
在 App 组件的 <head> 内容中,当不在 Development 环境中时应用 CSP:
@if (!Env.IsDevelopment())
{
<HeadContent>
<meta ...>
</HeadContent>
}
或者,使用前面的代码,但在 Layout 文件夹中按布局应用 CSP。 确保每个布局都指定一个 CSP。
元标记限制
<meta> 标记策略不支持以下指令:
要支持上述指令,请使用名为 Content-Security-Policy 的标头。 指令字符串是标头的值。
测试策略并接收违规报告
测试有助于确认在生成初始策略时不会无意中阻止第三方脚本。
要在不强制实施策略指令的情况下在一段时间内测试策略,请将基于标头的策略的 <meta> 标记的 http-equiv 属性或标头名称设置为 Content-Security-Policy-Report-Only。 将故障报告作为 JSON 文档发送到指定的 URL。 有关详细信息,请参阅 MDN Web 文档:Content-Security-Policy-Report-Only。
要在策略处于活动状态时报告违规,请参阅以下文章:
虽然不再建议使用 report-uri,但在所有主要浏览器都支持 report-to 之前,都应使用这两个指令。 不要只使用 report-uri,因为随时可能从浏览器中删除对 report-uri 的支持 。 完全支持 report-uri 时,请删除策略中对 report-to 的支持。 要跟踪 report-to 的使用情况,请参阅我可以使用:report-to。
每次发布时测试和更新应用的策略。
疑难解答
- 浏览器的开发人员工具控制台中出现错误。 浏览器提供以下信息:
- 不符合策略的元素。
- 如何修改策略以允许遭到阻止的项目。
- 仅当客户端的浏览器支持所有包含的指令时,策略才完全有效。 有关当前浏览器支持矩阵,请参阅我可以使用:Content-Security-Policy。