当前位置: 首页 > 知识库问答 >
问题:

如何验证HTTP重定向绑定的SAML签名

彭涵衍
2023-03-14

我正在通过HTTP-重定向绑定接收SAML请求,SAML请求的内容如下

{"SigAlg"=

它还有一个签名值

2.在一个新的研究的基础上,在一个新的研究的基础上,在一个新的研究的基础上,在一个新的研究的基础上,在一个新的研究的基础上,在一个新的研究的基础上,在一个新的研究的基础上,在一个新的研究的一个新的研究(2)在一个新的研究(2)在一个新的研究的一个新的研究(2)在一个新的研究(2)的研究(2)在一个新的(2)2 2 2 2 2 2(2)2(2)2(2)2(2(2)2)2(2)2(2)2)在2(2)2(2(2)2)2)2)2(2(2)2(2)2(2)2)2(2)2(2(2)2)2(2(2)2)2(2(2(2)2)在2(2)2)在2)嗯==

但是我不明白如何验证这个签名是正确的。

第3.4.4.1节SAML绑定https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf

To construct the signature, a string consisting of the concatenation of the RelayState (if present),
SigAlg, and SAMLRequest (or SAMLResponse) query string parameters (each one URLencoded)
is constructed in one of the following ways (ordered as below):
SAMLRequest=value&RelayState=value&SigAlg=value
SAMLResponse=value&RelayState=value&SigAlg=value

我试过方法但是

>

此外,我无法使用私钥解密签名消息(我假设签名是使用我与之联合的公共创建的。)

<samlp:LogoutRequest ID="_36167d94-d868-4c04-aee3-8bbd4ed91317" Version="2.0" IssueInstant="2017-01-05T16:21:55.704Z" Destination="https://werain.me/" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">urn:federation:MicrosoftOnline</Issuer><NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">4948f6ce-4e3b-4538-b284-1461f9379b48</NameID><samlp:SessionIndex>_eafbb730-b590-0134-a918-00d202739c81</samlp:SessionIndex></samlp:LogoutRequest>

这里有任何帮助。

共有3个答案

谭梓
2023-03-14

根据绑定(POST或重定向)的不同,SAML 2.0签名的验证方式不同。如果使用POST绑定,则在SAML XML中验证签名。如果使用重定向绑定,则使用签名验证查询字符串。

此LogoutRequest通过重定向绑定发送。下面的C#示例代码是从ITfoxtec复制的。身份Saml2组件,并演示如何验证签名。

var queryString = request.QueryString;
var signatureValue = Convert.FromBase64String(request.Query["Signature"]);

var messageName = "SAMLRequest";
var signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
var signatureValidationCertificate = new X509Certificate2("path-to-service-provider-x509-certificate");

var saml2Sign = new Saml2SignedText(signatureValidationCertificate, signatureAlgorithm);
if (saml2Sign.CheckSignature(Encoding.UTF8.GetBytes(new RawSaml2QueryString(queryString, messageName).SignedQueryString), signatureValue))
{
    // Signature is valid.
}
else
{
    throw new InvalidSignatureException("Signature is invalid.");
}
  • 代码从Saml2ReDirect绑定复制
  • RawSaml2QueryString
  • Saml2SignedText
卓致远
2023-03-14

我正在尝试使用上述答案,但没有成功。

然后,阅读文档,花点时间,我成功地用Java验证了签名,快速的答案是:

final String samlRequest = request.getParameter("SAMLRequest");
final String relayState = request.getParameter("RelayState");
final String sigAlg = request.getParameter("SigAlg");
final String signature = request.getParameter("Signature");

FileInputStream fis = new FileInputStream(new File("path-to-service-provider-x509-certificate"));

CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(fis);

// ps: java.net.URLEncoder;
String query = "SAMLRequest=" + URLEncoder.encode(samlRequest, "UTF-8");
query += "&RelayState=" +URLEncoder.encode(relayState, "UTF-8");
query += "&SigAlg=" + URLEncoder.encode(sigAlg, "UTF-8");

// ps: org.opensaml.xml.util.Base64
byte[] signatureBytes = Base64.decode(signature);

org.apache.xml.security.Init.init();
Signature sig = Signature.getInstance("SHA1withRSA"); // or other alg (i, e: SHA256WithRSA or others)
sig.initVerify(cert.getPublicKey());
sig.update(query.getBytes());
Boolean valid = sig.verify(signatureBytes);
邢弘业
2023-03-14

SAML身份验证消息是带有嵌入(封装)XMLDSig签名或压缩编码签名的XML文档

包络XMLDSign签名

<samlp:LogoutRequest>
    <...saml message...> 
    <ds:Signature>
         <ds:SignedInfo />
         <ds:SignatureValue /> 
         <ds:KeyInfo /> 
    </ds:Signature> 
</samlp:LogoutRequest>

<代码>

在URL中压缩编码

SAMLRequest=value&RelayState=value&SigAlg=value&Signature=value

其中每个值都是url编码的

SAMLRequest=urlencode(base64(<samlp:LogoutRequest> <...saml message...> </samlp:LogoutRequest>))

使用算法SigAlg

Signature = urlencode( base64 ( SigAlg ("SAMLRequest=value&RelayState=value&SigAlg=value")))

SAML消息的数字签名

SAML消息用发行者(SP)的私钥进行数字签名(未加密),并可以用SP的公钥进行验证。SAML响应必须用身份提供者(IdP)的私钥签名,SP可以用IdP的公钥验证消息。

如果您担任IdP,并且希望验证SP的SAML请求,则需要:

>

授权请求:验证签名者的身份是否可以执行请求的操作。通常,您必须将证书的序列号或主题与预先存在的列表相匹配,或者验证证书是否由受信任的证书颁发机构颁发

生成SAML响应:使用SAML数据生成一条XML消息,并使用私钥对其进行签名,以发送到SP

大多数编程语言支持XMLDsig签名,但在您的情况下,使用的是压缩编码,这是SAML绑定的一个特定特征,因此如果您的SAML库不支持它,您必须手动验证签名。根据规范,这些或多或少是要遵循的步骤

 //get params from query string 
String samlrequest = getQueryParam("SAMLRequest");
String relaystate = getQueryParam("RelayState");
String sigalg = getQueryParam("SigAlg");
String signature = getQueryParam("Signature");


//The signature
byte signature[] = URLDecoder.decode(Base64.getDecoder().decode(signature ), "UTF-8");

//The signed data. build the following string checking if RelayState is null
//SAMLRequest=samlrequest&RelayState=relaystate&SigAlg=sigalg
byte signedData[] = concat(samlrequest,relaystate,sigalg);

//The signature algorithm could be "SHA1WithRSA" or "SHA1withDSA" depending on sigalg is http://www.w3.org/2000/09/xmldsig#rsa-sha1 or http://www.w3.org/2000/09/xmldsig#dsa-sha1 
String signatureAlgorithm = extractSignatureAlgorithm(sigalg);

//get the public key of the SP. It must be registered before this process
PublicKey publicKey = ...

//Verify the signature
Signature sig = Signature.getInstance(signatureAlgorithm);
sig.initVerify(publicKey);
sig.update(signedData); 
boolean verifies = sig.verify(signature);  
 类似资料:
  • 我正在尝试为重定向绑定创建SAML AuthnRequest。 这是我的(匿名)授权请求: 我有一个中继状态: SigAlg是http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 我对请求进行放气,然后进行base64编码,然后进行URL编码。(缩小后的base64编码结果在SAMLTool解码器中检出。) 用于创建签名的结果字符串如下所示: 我尝试使

  • 此查询是对后HTTP重定向绑定SAML请求中提出的问题的补充。 我试图通过HTTP重定向绑定发送SAML身份验证请求来实现dotnet SSO解决方案。在生成SAML AuthnRequest并使用SP的私有证书计算签名之后,我尝试了两种方法将签名添加到url中。 > < li> 生成SAML验证请求XML。 使用生成XML签名标签的SAML AuthnRequest XML计算签名,如下所示 在

  • 我们正在研究在我们的应用程序中实施基于SAML的SSO身份验证,我想知道是否可以通过SAML指定自定义重定向URL。换句话说,我们可以在身份提供者中配置一个服务提供者,并让服务提供者通过SAML请求指定身份提供者在登录后应将用户重定向到哪里? 我们之所以要寻找这样的东西,是因为我们的应用程序运行在不同的服务器上,这取决于它们所处的开发阶段(开发、测试、暂存、生产)。如果我们不必为要迁移到SAML

  • 我们的一个客户正在为他们的标识提供程序提供包含参数的URL。元数据如下所示(为简洁起见,进行了大量缩写): 可以看到,有一个名为“parameter”的参数,其值为“value”。生成的重定向URL中不存在此参数。我稍微调试了一下,发现从绑定(对于HTTP重定向来说是)获取,并委托对消息进行编码。编码器依次在其方法中执行以下操作: 所以出于某种原因,参数被故意无条件地剥离。 为什么会这样?我如何才

  • 我已经配置了一个SAML2。Okta中的0 IdP(即Okta是SAML2.0 SP)。 通过SAML成功完成IdP启动的身份验证后,我希望用户被重定向到自定义应用程序。因此,我将Okta(SP)上的“中继状态”配置为h_ttps://mydomain/customApp/customPath. 但是,出于安全原因,我认为SP没有将用户重定向到绝对URL,而是将get重定向到h_ttps://my

  • 我将spring saml扩展与Apache2.2+Tomcat7.0+OKTA(IdP)一起使用。securitycontext.xml如下所示: MetadataGeneratorFilter: 谢谢 奈良 HTTP请求转储: