权限策略

权限策略 提供了机制,允许 Web 开发人员明确声明哪些功能可以在网站上使用,哪些功能不能使用。您可以定义一组“策略”,限制网站代码可以访问哪些 API,或者修改浏览器针对某些功能的默认行为。这使您能够执行最佳实践,即使代码库在不断发展,并且可以更安全地组合第三方内容。

权限策略类似于 内容安全策略,但它控制功能而不是安全行为。

您可以使用权限策略执行的操作示例

  • 更改移动设备和第三方视频上自动播放的默认行为。
  • 限制网站使用相机、麦克风或扬声器等敏感设备。
  • 允许 iframe 使用 全屏 API
  • 阻止在视窗中不可见的项目被脚本化,以提高性能。

注意: 权限策略以前称为功能策略。名称已更改,HTTP 标头语法也已更改,因此如果您以前使用过功能策略,请记住这一点,并查看浏览器支持表。<iframe allow=" ... ">语法保持不变。

概念和用法

网络提供了功能和 API,如果滥用,可能会存在隐私或安全风险。在这种情况下,您可能希望严格限制如何在网站上使用功能。在每种情况下,都应有一种直观或不中断的方式让 Web 开发人员检测和处理功能被禁用的情况。

一些方法包括

  • 对于需要用户权限授予的 JavaScript API,将返回“权限被拒绝”。
  • 提供对功能访问权限的 JavaScript API 返回false 值或抛出错误。
  • API 甚至不会公开,就好像它们不存在一样。
  • 控制功能行为的选项具有不同的默认值。

注意: 新引入的功能可能具有明确的 API 来发出信号状态。后来与权限策略集成的现有功能通常会使用现有机制。

权限策略允许您控制哪些来源可以使用哪些功能,无论是在顶层页面还是在嵌入式 <iframe> 中。目标是执行良好用户体验的最佳实践,并提供对敏感强大功能的粒度控制(即需要用户明确授权才能使用其相关代码才能执行的功能)。

权限策略提供两种指定策略的方法

这些是独立但相关的 - 请参阅 嵌入式内容的策略继承 了解更多详细信息。

注意: 脚本可以通过 FeaturePolicy 对象以编程方式查询有关权限策略的信息,该对象位于 Document.featurePolicyHTMLIFrameElement.featurePolicy 中。

要控制每个功能,您需要编写一个策略,该策略包含

  • 一个指令,用于标识要控制的功能的名称。请参阅 不同可用指令的列表
  • 一个允许列表,这是一个应控制功能的来源列表。您可以为所有来源或特定来源启用功能,或阻止其在所有来源中的使用。

请参阅以下多个示例。

与权限 API 的关系

权限策略和 权限 API 紧密相关,但不同。这些技术控制其权限的功能重叠。

  • 权限策略允许服务器设置功能是否可以在特定文档(或其中的嵌入式 <frame>)中使用。这些被称为策略控制功能 - 请参阅 权限策略指令列表
  • 权限 API 根据用户授予的权限来控制对功能的访问。这些功能记录在 权限注册表 中。

用于每个功能的标识字符串在两者之间保持一致,例如,对于 地理定位 API,使用 geolocation。权限注册表中的大多数 API 功能也都有相应的权限策略指令。一个例外是 通知 API

通常,当权限策略阻止使用强大功能时,甚至不会要求用户授予使用权限,并且权限 API query() 方法将返回 statedenied

另请参阅 权限 > 与权限策略规范的关系

允许列表

允许列表是包含一个或多个以下值的来源列表,这些值包含在括号中,并用空格隔开

  • *:此文档中以及所有嵌套浏览上下文(<iframe>)中(无论其来源如何)都将允许使用该功能。
  • ()(空允许列表):在顶层和嵌套浏览上下文中禁用该功能。对于 <iframe> allow 属性,等效项是 'none'
  • self:此文档中以及所有嵌套浏览上下文(<iframe>)中(仅在同一来源中)将允许使用该功能。在嵌套浏览上下文中,跨来源文档中不允许使用该功能。self 可以被视为 https://your-site.example.com 的简写。对于 <iframe> allow 属性,等效项是 'self'
  • 'src':只要加载到其中的文档来自其 src 属性中 URL 的同一来源,该功能就在此 <iframe> 中允许使用。此值仅在 <iframe> allow 属性中使用,并且是 <iframe> 中的默认允许列表值。
  • "<origin>":该功能对于特定来源是允许的(例如,"https://a.example.com")。来源应使用空格隔开。请注意,<iframe> 允许属性中的来源没有引号。

*() 只能单独使用,而 selfsrc 可以与一个或多个来源结合使用。

注意: 指令具有默认允许列表,对于 Permissions-Policy HTTP 标头,该列表始终是 *selfnone 之一,并且在策略中未明确列出时,它会控制默认行为。这些在各个 指令参考页 上指定。对于 <iframe> allow 属性,默认行为始终是 src

在支持的情况下,您可以在权限策略来源中包含通配符。这意味着,您不必在允许列表中明确指定几个不同的子域,而可以将它们全部指定在具有通配符的单个来源中。

因此,您可以指定以下内容,而不是

http
("https://example.com" "https://a.example.com" "https://b.example.com" "https://c.example.com")

您可以指定

http
("https://example.com" "https://*.example.com")

注意: "https://*.example.com" 不匹配 "https://example.com"

允许列表示例

  • *
  • ()
  • (self)
  • (src)
  • ("https://a.example.com")
  • ("https://a.example.com" "https://b.example.com")
  • (self "https://a.example.com" "https://b.example.com")
  • (src "https://a.example.com" "https://b.example.com")
  • ("https://*.example.com")

Permissions-Policy 报头语法

一般语法如下所示

http
Permissions-Policy: <directive>=<allowlist>

例如,要阻止对地理定位的所有访问,您可以执行以下操作

http
Permissions-Policy: geolocation=()

或者,要允许访问一部分来源,您可以执行以下操作

http
Permissions-Policy: geolocation=(self "https://a.example.com" "https://b.example.com")

通过使用逗号分隔的策略列表发送标头或为每个策略发送单独的标头,可以同时控制多个功能。

例如,以下操作是等效的

http
Permissions-Policy: picture-in-picture=(), geolocation=(self "https://example.com"), camera=*;

Permissions-Policy: picture-in-picture=()
Permissions-Policy: geolocation=(self "https://example.com")
Permissions-Policy: camera=*

嵌入式框架语法

对于 <iframe> 要启用其允许来源的功能,该来源也必须位于父页面的允许列表中。由于这种 继承行为,最好在 HTTP 标头中指定功能的最广泛可接受支持,然后在每个 <iframe> 中指定您需要的支持子集。

一般语法如下所示

html
<iframe src="<origin>" allow="<directive> <allowlist>"></iframe>

例如,要阻止对地理定位的所有访问,您可以执行以下操作

html
<iframe src="https://example.com" allow="geolocation 'none'"></iframe>

要将策略应用于当前来源和其他来源,您可以执行以下操作

html
<iframe
  src="https://example.com"
  allow="geolocation 'self' https://a.example.com https://b.example.com"></iframe>

这一点很重要:默认情况下,如果 <iframe> 导航到另一个来源,则不会将策略应用于 <iframe> 导航到的来源。通过在 allow 属性中列出 <iframe> 导航到的来源,应用于原始 <iframe> 的权限策略将应用于 <iframe> 导航到的来源。

通过在 allow 属性中包含用分号分隔的策略指令列表,可以同时控制多个功能。

html
<iframe
  src="https://example.com"
  allow="geolocation 'self' https://a.example.com https://b.example.com; fullscreen 'none'"></iframe>

值得特别说明一下src的值。我们上面提到,使用此允许列表值将意味着允许在该<iframe>中使用关联的功能,只要加载到其中的文档来自与其src属性中的URL相同的来源即可。此值是allow中列出的功能的默认allowlist值,因此以下等效

html
<iframe src="https://example.com" allow="geolocation 'src'">
  <iframe src="https://example.com" allow="geolocation"></iframe
></iframe>

注意:正如您所注意到的,<iframe>策略的语法与Permissions-Policy标头的语法略有不同。前者仍然使用与旧的 Feature Policy 规范相同的语法,该规范已被 Permissions Policy 取代。

围栏帧和权限策略

<fencedframe><iframe>以相同的方式与权限策略交互,但功能更加受限。只有专门设计用于<fencedframes>的功能才能通过为其设置的权限策略启用;在此上下文中其他受策略控制的功能不可用。

有关更多详细信息,请参阅围栏帧可用的权限策略

嵌入式内容的策略继承

脚本会继承其浏览上下文的策略,无论其来源如何。这意味着顶级脚本会从主文档继承策略。

所有<iframe>都会继承其父页面的策略。如果<iframe>具有allow属性并且父页面具有Permissions-Policy,则会结合父页面的策略和allow属性,使用最严格的子集。要启用<iframe>的功能,其来源必须同时存在于父页面的允许列表和allow属性中。

在策略中禁用功能是单向切换。如果父帧已为子帧禁用了某项功能,则子帧无法重新启用该功能,其任何后代也无法重新启用。

示例

组合 HTTP 标头和<iframe>策略

例如,假设我们想在自己的来源和来自我们信任的广告网络的嵌入内容中启用地理位置使用。我们可以这样设置页面范围的权限策略

http
Permissions-Policy: geolocation=(self "https://trusted-ad-network.com")

在我们自己的广告<iframe>中,我们可以这样设置对https://trusted-ad-network.com来源的访问

html
<iframe src="https://trusted-ad-network.com" allow="geolocation"></iframe>

如果其他来源最终加载到<iframe>中,它将无法访问地理位置。

html
<iframe src="https://rogue-origin-example.com" allow="geolocation"></iframe>

规范

规范
权限策略
# permissions-policy-http-header-field

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参见