You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails+Devise集成SAML认证遇签名验证失败问题

Devise SAML Authenticatable集成AD FS时签名验证失败问题

我正在使用Devise SAML Authenticatable gem为Ruby on Rails应用集成SAML认证,有Devise使用经验但首次接触SAML集成。核心需求是确保应用能通过AD FS(IdP)安全认证用户,且所有SAML消息符合IdP要求的签名规范,但目前遇到SAML认证请求签名错误,无法通过验证。

当前SAML配置代码

config.saml_configure do |settings|
  private_key_path = Rails.root.join('config', 'cert', 'private.pem')
  certificate_path = Rails.root.join('config', 'cert', 'certificate.crt')
  idp_cert_path = Rails.root.join('config', 'cert', 'sts_example.cer')

  if File.exist?(private_key_path) && File.exist?(certificate_path) && File.exist?(idp_cert_path)
    settings.private_key = File.read(private_key_path)
    settings.certificate = File.read(certificate_path)
    settings.idp_cert = File.read(idp_cert_path)
  else
    Rails.logger.error "SAML configuration error: One or more certificate files are missing."
  end

  settings.assertion_consumer_service_url = ENV.fetch('WSFED_REPLY_URL', 'https://dev.example.com/users/sso/auth')
  settings.issuer = 'https://dev.example.com/users/sso/metadata'
  settings.assertion_consumer_service_binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
  settings.name_identifier_format = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
  settings.sp_entity_id = ENV['WSFED_ISSUER']
  settings.idp_slo_service_url = ENV['WSFED_SLO_URL']
  settings.idp_slo_target_url = ENV['WSFED_SLO_URL']
  settings.idp_sso_service_url = ENV['WSFED_SSO_URL']
  settings.idp_sso_target_url = ENV['WSFED_SSO_URL']
  settings.idp_cert_fingerprint_algorithm = 'http://www.w3.org/2000/09/xmldsig#sha256'
  settings.authn_context = ""
  settings.idp_cert_fingerprint = "HEX"

  settings.security[:authn_requests_signed] = true
  settings.security[:logout_requests_signed] = true
  settings.security[:logout_responses_signed] = true
  settings.security[:want_assertions_signed] = true
  settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
end

AD FS返回的错误信息

异常详情:
Microsoft.IdentityModel.Protocols.XmlSignature.SignatureVerificationFailedException: MSIS0038 : SAML消息签名错误。签发者: « http://example.com/adfs/services/trust »。

问题排查及解决建议

1. 验证SP密钥与证书的匹配性

确保private.pem和certificate.crt是一对有效的密钥对,且采用SHA256算法生成。可以用以下OpenSSL命令验证:

openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in private.pem | openssl md5

两个命令输出的哈希值必须完全一致,说明密钥和证书匹配。

2. 清理IdP证书配置冲突

你同时配置了settings.idp_cert(完整证书)和settings.idp_cert_fingerprint(证书指纹),AD FS通常只需要其中一种配置。建议删除settings.idp_cert_fingerprint = "HEX"这一行,仅保留完整的IdP证书配置,因为指纹容易因格式(如空格、大小写、算法不匹配)导致验证失败。同时确认sts_example.cer是AD FS导出的Base64编码CER格式证书,而非PFX格式。

3. 对齐签名算法配置

  • 确认AD FS信赖方配置中要求的签名算法为SHA256(在AD FS管理控制台的对应信赖方“高级”标签中查看),与你配置的XMLSecurity::Document::RSA_SHA256一致。
  • 确保settings.idp_cert_fingerprint_algorithm的取值和AD FS证书的指纹算法一致,当前配置的SHA256是主流标准,若AD FS使用SHA1则需修改(不推荐继续使用SHA1)。

4. 修正实体ID与Issuer配置

错误提示中的签发者是http://example.com/adfs/services/trust,需检查以下配置:

  • settings.sp_entity_id必须与AD FS中信赖方配置的标识符完全一致,包括协议(http/https)、域名和路径,且大小写匹配。
  • settings.issuer应设置为与sp_entity_id相同的值,而非Metadata的URL,因为Issuer代表SP的实体标识,必须被AD FS信赖方识别。

5. 检查SAML请求的签名覆盖范围

使用SAML Tracer等浏览器插件捕获发送给AD FS的AuthnRequest,确认签名覆盖了整个请求文档,而非部分元素。AD FS通常要求对整个AuthnRequest进行签名,若签名范围不符合要求,会触发验证失败。


内容的提问来源于stack exchange,提问作者Merouane Amqor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:41:10