如何验证ADFS加密的SAML响应(Assertion)
关于ADFS返回SAML响应的验证相关问题解答
1. 解密拿到Claims后是否仍需验证SAML响应
必须验证。解密操作仅能证明SAML响应是用你的服务提供商(SP)公钥加密、只有你持有对应私钥可以解密读取内容,完全无法证明响应由合法的ADFS身份提供商签发,也无法证明传输过程中内容没有被篡改。攻击者完全可以自行构造伪造的身份声明,用你的SP公钥加密后发送给你的服务端,跳过验证步骤会直接导致身份伪造漏洞,存在极高安全风险。
2. 验证是否需要IDP公钥、公钥获取渠道
- 必须使用ADFS作为身份提供商的签名公钥完成验证
- 该公钥默认包含在ADFS提供的IDP元数据(Metadata)中,对应元数据里
use="signing"属性的<md:KeyDescriptor>节点下的X.509证书,直接从元数据提取即可,不要通过其他非官方渠道获取公钥,避免遭遇劫持攻击。
3. 基于现有请求参数的验证操作步骤
你当前拿到的是HTTP-Redirect绑定下的SAML响应参数,按以下步骤完成签名验证:
- 构造待验证的原始签名串
- 参数顺序严格遵循:
SAMLResponse→RelayState(如果请求中存在该参数) →SigAlg,不得调整顺序 - 所有参数的键和值都按照RFC 3986标准做URL编码
- 用
&拼接编码后的键值对,无RelayState时拼接结果为:SAMLResponse=<URL编码后的SAMLResponse参数值>&SigAlg=<URL编码后的sigAlg参数值>
- 参数顺序严格遵循:
- 处理拿到的签名值:对
signature参数做Base64解码,得到原始二进制签名内容 - 执行验签操作:使用从IDP元数据中提取的签名公钥,结合指定的签名算法
sha256,对第一步构造的原始签名串做验签,与第二步解码得到的签名内容匹配即代表签名有效 - 补充必填校验项:除签名外你还需要校验SAML断言的以下内容,避免风险:
- 断言Issuer字段与ADFS的实体ID完全一致
- 断言Audience字段与你的SP实体ID完全一致
- 断言的生效时间、过期时间覆盖当前时间
- 断言中Subject的NameID格式符合你业务的预期要求
内容的提问来源于stack exchange,提问作者Kadhiresh Gajendiran
相关产品推荐
相关产品推荐

