使用 AD FS 2019 自定义 HTTP 安全响应标头

Active Directory 联合身份验证服务 (AD FS) 2019 添加了自定义 AD FS 发送的 HTTP 安全响应标头的功能。 这些工具可帮助管理员防范常见的安全漏洞,并允许他们利用基于浏览器的保护机制的最新改进。 此功能来自引入的两个新 cmdlet:Get-AdfsResponseHeadersSet-AdfsResponseHeaders

注意

通过使用 cmdlet Get-AdfsResponseHeadersSet-AdfsResponseHeaders 自定义 HTTP 安全响应标头(CORS 标头除外)的功能已向后移植到 AD FS 2016。 可以通过安装 KB4493473KB4507459 将该功能添加到 AD FS 2016。

本文档讨论常用的安全响应标头,演示如何自定义 AD FS 2019 发送的标头。

注意

本文假定已安装 AD FS 2019。

方案

以下方案演示了管理员可能需要自定义安全标头的情况。

  • 管理员已启用 HTTP Strict-Transport-Security (HSTS),以保护可能通过使用 HTTP 从可能遭到黑客攻击的公共 WiFi 访问点访问 Web 应用程序的用户。 HSTS 强制所有连接通过 HTTPS 加密。 他们希望通过为子域启用 HSTS 来进一步增强安全性。
  • 管理员已配置 X-Frame-Options 响应标头,以防止网页遭点击劫持。 X-Frame-Options 可防止在 iFrame 中呈现任何网页。 但是,由于新的业务要求(在 iFrame 中显示来自不同源(域)的应用程序中的数据),他们需要自定义标头值。
  • 管理员已启用 X-XSS-Protection,在浏览器检测到跨脚本攻击时清理和阻止页面。 X-XSS-Protection 可防止跨脚本攻击。 但是,他们需要自定义标头,以允许加载清理后的页面。
  • 管理员需要启用跨域资源共享 (CORS),并且需要 AD FS 上设置源(域),以允许单页应用程序访问其他域的 Web API。
  • 管理员已启用内容安全策略 (CSP) 标头,通过禁止任何跨域请求来防止跨站点脚本和数据注入攻击。 但是,由于新的业务要求,他们需要自定义标头,以允许网页从任何源加载图像,并将媒体限制为受信任的提供商。

HTTP 安全响应标头

AD FS 在发送到 Web 浏览器的传出 HTTP 响应中包含响应标头。 可以使用 Get-AdfsResponseHeaders 列出标头,如以下屏幕截图所示。

Screenshot that shows the PowerShell output from Get-AdfsResponseHeaders.

屏幕截图中的 ResponseHeaders 属性标识 AD FS 在每个 HTTP 响应中包含的安全标头。 仅当 ResponseHeadersEnabled 设置为 True(默认值)时,AD FS 才会发送响应标头。 可将该值设置为 False,以防止 AD FS 在 HTTP 响应中包含任何安全标头。 但是,不建议使用此设置。 可以使用以下命令将 ResponseHeaders 设置为 False

Set-AdfsResponseHeaders -EnableResponseHeaders $false

HTTP Strict-Transport-Security (HSTS)

HTTP Strict-Transport-Security (HSTS) 是一种 Web 安全策略机制,有助于减少具有 HTTP 和 HTTPS 终结点的服务的协议降级攻击和 Cookie 劫持。 它允许 Web 服务器声明 Web 浏览器或其他符合要求的用户代理只能通过使用 HTTPS 与其交互,而不能通过 HTTP 协议与其交互。

Web 身份验证流量的所有 AD FS 终结点都通过 HTTPS 专门打开。 因此,AD FS 有效缓解了 HTTP Strict Transport Security 策略机制带来的威胁。 默认情况下,不会降级到 HTTP,因为 HTTP 中没有侦听器。 可以通过设置以下参数来自定义标头:

  • max-age=<expire-time>. 到期时间(秒)指定应仅使用 HTTPS 访问站点的时长。 默认值和建议值为 31536000 秒(一年)。
  • includeSubDomains。 此参数是可选的。 如果指定,HSTS 规则也适用于所有子域。

HSTS 自定义

默认情况下,该标头处于启用状态,max-age 设置为 1 年;但管理员可以修改 max-age(不建议降低 max-age 值)或通过 Set-AdfsResponseHeaders cmdlet 为子域启用 HSTS。

Set-AdfsResponseHeaders -SetHeaderName "Strict-Transport-Security" -SetHeaderValue "max-age=<seconds>; includeSubDomains"

示例:

Set-AdfsResponseHeaders -SetHeaderName "Strict-Transport-Security" -SetHeaderValue "max-age=31536000; includeSubDomains"

默认情况下,该标头包含在 ResponseHeaders 属性中;但管理员可以通过 Set-AdfsResponseHeaders cmdlet 将其删除。

Set-AdfsResponseHeaders -RemoveHeaders "Strict-Transport-Security"

X-Frame-Options

默认情况下,AD FS 不允许外部应用程序在执行交互式登录时使用 iFrame。 此配置可防止某些形式的网络钓鱼攻击。 请注意,由于先前已建立会话级别安全性,因此可以通过 iFrame 执行非交互式登录。

但是,在极少数情况下,你可能信任特定应用程序,而该应用程序需要支持 iFrame 的交互式 AD FS 登录页。 为此,将使用 X-Frame-Options 标头。

此 HTTP 安全响应标头用于向浏览器传达它是否可以在 <frame>/<iframe> 中呈现页面。 标头可设置为下列值之一:

  • deny。 不显示框架中的页面。 此配置是默认设置和建议设置。
  • sameorigin。 仅当源与网页的源相同时,页面才会显示在框架中。 除非所有上级也位于同一个源中,否则该选项无效。
  • allow-from <specified origin>。 仅当源(例如 https://www.".com)与标头中的特定源匹配时,页面才会显示在框架中。 某些浏览器可能不支持此选项。

X-Frame-Options 自定义

默认情况下,该标头设置为“deny”;但管理员可以通过 Set-AdfsResponseHeaders cmdlet 修改该值。

Set-AdfsResponseHeaders -SetHeaderName "X-Frame-Options" -SetHeaderValue "<deny/sameorigin/allow-from<specified origin>>"

示例:

Set-AdfsResponseHeaders -SetHeaderName "X-Frame-Options" -SetHeaderValue "allow-from https://www.example.com"

默认情况下,该标头包含在 ResponseHeaders 属性中;但管理员可以通过 Set-AdfsResponseHeaders cmdlet 将其删除。

Set-AdfsResponseHeaders -RemoveHeaders "X-Frame-Options"

X-XSS-Protection

此 HTTP 安全响应标头用于在浏览器检测跨站点脚本 (XSS) 攻击时阻止加载网页。 此方法称为 XSS 筛选。 标头可设置为下列值之一:

  • 0 将禁用 XSS 筛选。 建议不要使用。
  • 1 将启用 XSS 筛选。 如果检测到 XSS 攻击,浏览器会清理页面。
  • 1; mode=block 将启用 XSS 筛选。 如果检测到 XSS 攻击,浏览器会阻止呈现页面。 此设置是默认设置和建议设置。

X-XSS-Protection 自定义

默认情况下,标头设置为 1; mode=block;。 但是,管理员可以通过 Set-AdfsResponseHeaders cmdlet 修改该值。

Set-AdfsResponseHeaders -SetHeaderName "X-XSS-Protection" -SetHeaderValue "<0/1/1; mode=block/1; report=<reporting-uri>>"

示例:

Set-AdfsResponseHeaders -SetHeaderName "X-XSS-Protection" -SetHeaderValue "1"

默认情况下,该标头包含在 ResponseHeaders 属性中;但管理员可以通过 Set-AdfsResponseHeaders cmdlet 将其删除。

Set-AdfsResponseHeaders -RemoveHeaders "X-XSS-Protection"

跨源资源共享 (CORS) 标头

Web 浏览器安全可防止网页发出从脚本内发起的跨域请求。 但是,可能需要访问其他源(域)中的资源。 跨域资源共享 (CORS) 是一项 W3C 标准,可让服务器放宽同域策略。 通过使用 CORS,服务器可以显式允许某些跨域请求,同时拒绝另一些跨域请求。

为了更好地了解 CORS 请求,以下方案演示了单页应用程序 (SPA) 需要调用其他域的 Web API 的情况。 此外,请考虑在 AD FS 2019 上配置 SPA 和 API,并且 AD FS 已启用 CORS。 AD FS 可以识别 HTTP 请求中的 CORS 标头、验证标头值,并在响应中包含相应的 CORS 标头。 有关如何在 AD FS 2019 上启用和配置 CORS 的详细信息,请参阅“CORS 自定义”部分。 以下示例流将演示整个方案:

  1. 用户通过客户端浏览器访问 SPA,并重定向到 AD FS 身份验证终结点进行身份验证。 由于 SPA 配置为隐式授权流,因此请求会在身份验证成功后向浏览器返回访问 + ID 令牌。

  2. 用户完成身份验证后,SPA 中包含的前端 JavaScript 发出访问 Web API 的请求。 该请求与以下标头一起重定向到 AD FS:

    • Options - 描述目标资源的通信选项。
    • Origin - 包括 Web API 的源。
    • Access-Control-Request-Method - 标识要在发出实际请求时使用的 HTTP 方法(例如 DELETE)。
    • Access-Control-Request-Headers - 标识要在发出实际请求时使用的 HTTP 标头。

    注意

    CORS 请求类似于标准 HTTP 请求, 但源标头的存在表明传入请求与 CORS 相关。

  3. AD FS 验证标头中包含的 Web API 源是否列在 AD FS 中配置的受信任源中。 有关如何修改受信任源的更多信息,请参阅 CORS 自定义。 然后,AD FS 使用以下标头进行响应:

    • Access-Control-Allow-Origin - 值与 Origin 标头中的值相同。
    • Access-Control-Allow-Method - 值与 Access-Control-Request-Method 标头中的值相同。
    • Access-Control-Allow-Headers - 值与 Access-Control-Request-Headers 标头中的值相同。
  4. 浏览器发送实际请求,包括以下标头:

    • HTTP 方法(例如 DELETE)。
    • Origin - 包括 Web API 的源。
    • Access-Control-Allow-Headers 响应标头中包含的所有标头。
  5. 验证后,AD FS 通过在 Access-Control-Allow-Origin 响应标头中包含 Web API 域(源)来批准请求。

  6. 通过包含 Access-Control-Allow-Origin 标头,可允许浏览器调用请求的 API。

CORS 自定义

默认情况下,不会启用 CORS 功能;但管理员可以通过 Set-AdfsResponseHeaders cmdlet 启用该功能。

Set-AdfsResponseHeaders -EnableCORS $true

启用后,管理员可以使用相同的 cmdlet 枚举受信任源的列表。 例如,以下命令允许来自源 https&#58;//example1.comhttps&#58;//example1.com 的 CORS 请求。

Set-AdfsResponseHeaders -CORSTrustedOrigins https://example1.com,https://example2.com

注意

管理员可以通过在受信任源的列表中包括 "*" 来允许来自任何源的 CORS 请求,但不建议使用此方法,因为这存在安全漏洞,如果选择这样做,系统会显示警告消息。

内容安全策略 (CSP)

此 HTTP 安全响应标头用于防止浏览器无意中执行恶意内容,从而防止跨站点脚本、点击劫持和其他数据注入攻击。 不支持内容安全策略 (CSP) 的浏览器将忽略 CSP 响应标头。

CSP 自定义

自定义 CSP 标头涉及修改定义允许浏览器为网页加载的资源的安全策略。 默认安全策略为:

Content-Security-Policy: default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:;

default-src 指令用于修改 -src 指令,而不显式列出每个指令。 例如,在下面的示例中,策略 1 与策略 2 相同。

策略 1

Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "default-src 'self'"

策略 2

Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "script-src 'self'; img-src 'self'; font-src 'self';
frame-src 'self'; manifest-src 'self'; media-src 'self';"

如果显式列出指令,则指定的值会替代为 default-src 指定的值。 在下面的示例中,img-src 采用值 '*' (允许从任何源加载图像),而其他 -src 指令会采用值 'self'(限制为与网页相同的源)。

Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "default-src 'self'; img-src *"

可以为 default-src 策略定义以下源:

  • 'self' - 通过指定此源,可将要加载的内容的源限制为网页的源。
  • 'unsafe-inline' - 通过在策略中指定此源,可使用内联 JavaScript 和 CSS。
  • 'unsafe-eval' - 通过在策略中指定此源,可使用文本到 JavaScript 机制(如 eval)。
  • 'none' - 通过指定此源,可限制从任何源加载内容。
  • data: - 通过指定 data: URI,可让内容创建者在文档中内联嵌入小文件。 不推荐使用。

注意

AD FS 在身份验证过程中使用 JavaScript,因此通过在默认策略中包含 'unsafe-inline' 和 'unsafe-eval' 源来启用 JavaScript。

自定义标头

除了上面列出的安全响应标头(HSTS、CSP、X-Frame-Options、X-XSS-Protection 和 CORS)之外,AD FS 2019 还支持设置新标头。

例如,可以将新标头 "TestHeader" 进而 "TestHeaderValue" 设置为值。

Set-AdfsResponseHeaders -SetHeaderName "TestHeader" -SetHeaderValue "TestHeaderValue"

设置后,将在 AD FS 响应中发送新标头,如以下 Fiddler 代码片段所示:

Screenshot of Fiddler on the headers tab that highlights TestHeader: TestHeaderValue under Miscellaneous.

Web 浏览器兼容性

使用下面的表和链接确定哪些 Web 浏览器与每个安全响应标头兼容。

HTTP 安全响应标头 浏览器兼容性
HTTP Strict-Transport-Security (HSTS) HSTS 浏览器兼容性
X-Frame-Options X-Frame-Options 浏览器兼容性
X-XSS-Protection X-XSS-Protection 浏览器兼容性
跨域资源共享 (CORS) CORS 浏览器兼容性
内容安全策略 (CSP) CSP 浏览器兼容性

下一步