文档目录
Permissions-Policy配置

简介

本文件面向DouPHP站点,提供Permissions-Policy安全响应头的落地方案。内容涵盖:

  • 在DouPHP中如何集中配置并下发Permissions-Policy头
  • 常用权限(camera、microphone、geolocation、payment、usb等)的启用/禁用策略
  • 最小权限原则的实践建议
  • 与Feature-Policy的关系及迁移注意事项
  • 权限检测与功能降级处理思路
  • 不同业务场景下的推荐配置模板

项目结构

DouPHP通过统一的中间件机制在HTTP边界下发安全响应头,其中包含X-Content-Type-Options、X-Frame-Options、Referrer-Policy以及Permissions-Policy。具体实现由基类中间件读取配置并写入响应头,前台、后台、API三端各自继承该基类以复用相同行为。

graph TB
A["请求进入"] --> B["前端中间件<br/>front/middleware/SecurityHeadersMiddleware"]
A --> C["后台中间件<br/>admin/middleware/SecurityHeadersMiddleware"]
A --> D["API中间件<br/>api/middleware/SecurityHeadersMiddleware"]
B --> E["基类中间件<br/>AbstractSecurityHeadersMiddleware"]
C --> E
D --> E
E --> F["读取配置<br/>config/security.php"]
E --> G["设置响应头<br/>包括 Permissions-Policy"]
G --> H["继续处理请求"]

核心组件

  • 安全响应头中间件基类:负责从配置中读取headers并写入响应头,包含Permissions-Policy。
  • 三端中间件薄壳:前台、后台、API分别继承基类,统一行为。
  • 安全配置:集中定义各安全头值,包括permissions_policy字段。

架构总览

下图展示了请求到达后,中间件如何读取配置并下发Permissions-Policy头,随后继续路由处理。

sequenceDiagram
participant Client as "客户端"
participant MW as "SecurityHeadersMiddleware(三端)"
participant BaseMW as "AbstractSecurityHeadersMiddleware"
participant CFG as "Config(security.headers)"
participant Next as "后续处理器"
Client->>MW : HTTP请求
MW->>BaseMW : handle(next)
BaseMW->>CFG : 读取 security.headers
BaseMW-->>BaseMW : 校验 headers_sent()
BaseMW->>Client : 设置 X-Content-Type-Options / X-Frame-Options / Referrer-Policy / Permissions-Policy
BaseMW->>Next : 继续处理请求
Next-->>Client : 业务响应

详细组件分析

安全响应头中间件基类

  • 职责:在管道最前置读取配置并下发一组基线安全头;仅在HTTPS且开启时下发HSTS;仅对已匹配路由生效。
  • 关键点:当配置项存在且未发送过响应头时,会写入对应响应头,包括Permissions-Policy。
flowchart TD
Start(["进入 handle"]) --> ReadCfg["读取 security.headers"]
ReadCfg --> CheckSent{"是否已发送响应头?"}
CheckSent -- "是" --> Skip["跳过设置"]
CheckSent -- "否" --> SetHeaders["设置安全头<br/>含 Permissions-Policy"]
SetHeaders --> Next["调用 next() 继续处理"]
Skip --> Next

三端中间件薄壳

  • 前台、后台、API均继承基类,不改变默认行为,确保三端一致地下发安全头。

安全配置(security.headers)

  • 位置:config/security.php中的security.headers数组。
  • 关键字段:
    • permissions_policy:字符串,空串表示关闭该头;非空则作为Permissions-Policy值下发。
    • 其他相关头:frame_options、content_type_options、referrer_policy、hsts。
  • 当前默认值示例:已包含对geolocation、microphone、camera的限制。

依赖关系分析

  • 中间件依赖配置:AbstractSecurityHeadersMiddleware通过配置中心读取security.headers,再写入响应头。
  • 三端复用:前台、后台、API中间件均依赖同一基类,保证一致性。
  • 运行时约束:仅在headers未发送时写入,避免重复或错误覆盖。
graph LR
CFG["config/security.php"] --> BASE["AbstractSecurityHeadersMiddleware"]
BASE --> FRONT["front SecurityHeadersMiddleware"]
BASE --> ADMIN["admin SecurityHeadersMiddleware"]
BASE --> API["api SecurityHeadersMiddleware"]

性能与安全考量

  • 性能:中间件仅在命中路由时执行,且仅在headers未发送时写入,开销极低。
  • 安全:
    • 通过集中配置统一管理,减少遗漏风险。
    • 默认限制敏感权限(如geolocation、microphone、camera),降低滥用面。
    • HSTS仅在HTTPS且显式开启时下发,避免误配导致不可逆问题。

故障排查指南

  • 现象:浏览器控制台提示某权限被拒绝(如“Geolocation denied”)。
    • 检查:确认config/security.php中permissions_policy是否限制了相应权限。
    • 调整:如需启用,修改对应权限值为允许源(例如自身域名或空列表表示允许所有,需谨慎评估)。
  • 现象:未看到Permissions-Policy响应头。
    • 检查:确认中间件已挂载到路由管道,且headers尚未发送。
    • 定位:查看AbstractSecurityHeadersMiddleware是否在handle阶段执行。
  • 现象:HSTS未生效。
    • 检查:是否为HTTPS环境且hsts.enabled为true。

结论

DouPHP通过集中化的安全响应头中间件和配置,提供了简单、一致的Permissions-Policy下发能力。建议遵循最小权限原则,按需启用敏感权限,并结合业务场景进行差异化配置。对于需要兼容旧版浏览器的场景,可考虑同时保留Feature-Policy作为过渡。

附录:场景化配置模板与迁移指南

常见权限说明与影响

  • camera:控制摄像头访问。限制后可防止网页任意调用摄像头,提升隐私保护。
  • microphone:控制麦克风访问。限制后可避免未经授权的音频采集。
  • geolocation:控制地理位置访问。限制后可阻止网页获取用户位置信息。
  • payment:控制支付API。限制后可避免第三方脚本触发支付流程。
  • usb:控制USB设备访问。限制后可防止恶意设备枚举与通信。

最小权限原则实践

  • 默认禁止敏感权限,仅在必要时放开给可信源。
  • 使用精确源(如自身域名)而非通配符,避免过度授权。
  • 定期审计页面与第三方脚本,及时收紧权限。

与Feature-Policy的关系与迁移

  • Feature-Policy是早期草案规范,Permissions-Policy是其演进版本,语义更清晰、支持更广。
  • 迁移建议:
    • 优先使用Permissions-Policy;若需兼容旧浏览器,可同时下发两者。
    • 逐步移除Feature-Policy,统一维护至Permissions-Policy。
    • 注意键名差异与取值变化,逐项核对。

权限检测与功能降级

  • 前端检测:在调用敏感API前,先检测权限状态,若被拒绝则提供降级方案(如引导用户手动授权或切换功能)。
  • 用户体验:明确告知用户权限被拒绝的原因与影响,并提供替代路径。
  • 后端配合:对关键操作增加服务端校验,避免仅依赖前端权限判断。

不同业务场景推荐配置模板

  • 纯展示型电商站点(无音视频、无定位)
    • 建议:保持默认限制(geolocation=(), microphone=(), camera=()),不启用payment、usb。
  • 直播/视频站点(需要摄像头、麦克风)
    • 建议:在必要页面启用camera、microphone,并限定可信源;其余页面保持限制。
  • 地图/本地服务站点(需要定位)
    • 建议:仅在地图相关页面启用geolocation,并限定可信源;其他页面保持限制。
  • 在线支付集成(需要payment)
    • 建议:仅在支付流程页面启用payment,严格限定可信源;其他页面保持限制。
  • 外设交互站点(需要usb)
    • 建议:仅在必要页面启用usb,严格限定可信源;其他页面保持限制。
添加日期:2026-10-05