SAML Basics

从零开始学习AWS黑客技术,成为 htARTE(HackTricks AWS红队专家)

支持HackTricks的其他方式:

SAML概述

**安全断言标记语言(SAML)**使身份提供者(IdP)能够向服务提供者(SP)发送授权凭据,实现单点登录(SSO)。这种方法通过允许在多个网站之间使用一组凭据来简化多个登录的管理。它利用XML在IdP和SP之间进行标准化通信,将用户身份的认证与服务授权联系起来。

SAML和OAuth的比较

  • SAML旨在为企业提供更大的SSO登录安全控制。

  • OAuth旨在更适合移动设备,使用JSON,并是来自Google和Twitter等公司的协作努力。

SAML认证流程

有关更多详细信息,请查看来自https://epi052.gitlab.io/notes-to-self/blog/2019-03-07-how-to-test-saml-a-methodology/的完整文章。这是一个摘要:

SAML认证过程涉及多个步骤,如图示:

  1. 资源访问尝试:用户尝试访问受保护的资源。

  2. 生成SAML请求:SP未识别用户并生成SAML请求。

  3. 重定向到IdP:用户被重定向到IdP,SAML请求通过用户的浏览器传递。

  4. IdP接收请求:IdP接收SAML请求。

  5. IdP身份验证:IdP对用户进行身份验证。

  6. 用户验证:IdP验证用户是否有权访问请求的资源。

  7. 生成SAML响应:IdP生成包含必要断言的SAML响应。

  8. 重定向到SP的ACS URL:用户被重定向到SP的断言消费者服务(ACS)URL。

  9. 验证SAML响应:ACS验证SAML响应。

  10. 授予资源访问权限:授予对最初请求的资源的访问权限。

SAML请求示例

考虑这样一个场景:用户请求访问https://shibdemo-sp1.test.edu/secure/上的安全资源。SP识别到缺乏身份验证,并生成一个SAML请求:

GET /secure/ HTTP/1.1
Host: shibdemo-sp1.test.edu
...

原始的 SAML 请求如下所示:

<?xml version="1.0"?>
<samlp:AuthnRequest ...
</samlp:AuthnRequest>

以下是此请求的关键要素:

  • AssertionConsumerServiceURL:指定 IdP 在身份验证后应将 SAML 响应发送到的位置。

  • Destination:发送请求的 IdP 地址。

  • ProtocolBinding:定义 SAML 协议消息的传输方法。

  • saml:Issuer:标识发起请求的实体。

在生成 SAML 请求后,SP 会以 302 重定向 响应,将浏览器重定向到 IdP,并在 HTTP 响应的 Location 标头中编码 SAML 请求。 RelayState 参数在整个交易过程中保持状态信息,确保 SP 在接收 SAML 响应时能识别最初的资源请求。 SAMLRequest 参数是原始 XML 片段的压缩和编码版本,使用 Deflate 压缩和 base64 编码。

SAML 响应示例

您可以在此处找到完整的 SAML 响应。响应的关键组件包括:

  • ds:Signature:这部分是 XML 签名,确保断言的发出者的完整性和真实性。示例中的 SAML 响应包含两个 ds:Signature 元素,一个用于消息,另一个用于断言。

  • saml:Assertion:此部分包含有关用户身份以及可能的其他属性的信息。

  • saml:Subject:指定断言中所有语句的主体主题。

  • saml:StatusCode:表示响应对应请求的操作状态。

  • saml:Conditions:详细说明断言的有效时间和指定的服务提供商等条件。

  • saml:AuthnStatement:确认 IdP 对断言的主体进行了身份验证。

  • saml:AttributeStatement:包含描述断言主体的属性。

在 SAML 响应之后,流程包括 IdP 发出的 302 重定向。这导致向服务提供商的 Assertion Consumer Service (ACS) URL 发送 POST 请求。POST 请求包括 RelayStateSAMLResponse 参数。ACS 负责处理和验证 SAML 响应。

收到 POST 请求并验证 SAML 响应后,将授予用户最初请求的受保护资源的访问权限。这通过向 /secure/ 端点发出 GET 请求和 200 OK 响应来说明,表示成功访问资源。

XML 签名

XML 签名具有多功能性,能够签署整个 XML 树或其中的特定元素。它们可以应用于任何 XML 对象,而不仅仅是响应元素。以下是 XML 签名的关键类型:

XML 签名的基本结构

XML 签名由如下基本元素组成:

<Signature>
<SignedInfo>
<CanonicalizationMethod />
<SignatureMethod />
<Reference>
<Transforms />
<DigestMethod />
<DigestValue />
</Reference>
...
</SignedInfo>
<SignatureValue />
<KeyInfo />
<Object />
</Signature>

每个Reference元素表示一个特定的资源被签名,可通过URI属性进行识别。

XML签名类型

  1. 包含签名:这种类型的签名是资源的后代,意味着签名包含在与签名内容相同的XML结构中。

示例:

<samlp:Response ... ID="..." ... >
...
<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#...">
...
</ds:Reference>
</ds:SignedInfo>
</ds:Signature>
...
</samlp:Response>

在包含签名中,ds:Transform元素指定通过enveloped-signature算法进行包含。

  1. 包裹签名:与包含签名相反,包裹签名将被签名的资源包装起来。

示例:

<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#...">
...
</ds:Reference>
</ds:SignedInfo>
<samlp:Response ... ID="..." ... >
...
</samlp:Response>
</ds:Signature>
  1. 分离签名:这种类型与其签名的内容是分离的。签名和内容是独立存在的,但两者之间保持链接。

示例:

<samlp:Response ... ID="..." ... >
...
</samlp:Response>
<ds:Signature>
<ds:SignedInfo>
...
<ds:Reference URI="#...">
...
</ds:Reference>
</ds:SignedInfo>
</ds:Signature>

总之,XML签名提供了灵活的方式来保护XML文档,每种类型都满足不同的结构和安全需求。

参考资料

最后更新于