简体   繁体   English

无法使用ColdFusion验证SAML断言

[英]Unable to validate SAML assertion with ColdFusion

We are receiving a standard SAML 2.0 assertion from an Identify Provider, and I am unable to validate it using the only example ColdFusion 9 example code that exists on the internet. 我们从身份提供者处收到标准的SAML 2.0声明,但我无法使用Internet上存在的唯一示例ColdFusion 9示例代码来验证它。

The code below can be found on the internet as an example of how to validate SAML with ColdFusion. 可以在互联网上找到以下代码,作为如何使用ColdFusion验证SAML的示例。 See this page: http://blog.tagworldwide.com/?p=19 参见本页: http : //blog.tagworldwide.com/?p=19

The SAML XML is being sent to us as a form post. SAML XML作为表单发布发送给我们。 We've got a page set up to detect the incoming assertion. 我们已经建立了一个页面来检测传入的断言。 The relevant code is below: 相关代码如下:

xmlResponse = getHttpRequestData().content.Trim();
docElement = XmlParse(variables.xmlResponse);

Init = CreateObject("Java", "org.apache.xml.security.Init").Init().init();

SignatureConstants = CreateObject("Java", "org.apache.xml.security.utils.Constants");
SignatureSpecNS = SignatureConstants.SignatureSpecNS;
xmlSignatureClass = CreateObject("Java", "org.apache.xml.security.signature.XMLSignature");
xmlSignature = xmlSignatureClass.init(docElement.getElementsByTagNameNS(SignatureSpecNS,"Signature").item(0),"");

keyInfo = xmlSignature.getKeyInfo();
X509CertificateResolverCN = "org.apache.xml.security.keys.keyresolver.implementations.X509CertificateResolver";
keyResolver = CreateObject("Java", X509CertificateResolverCN).init();
keyInfo.registerInternalKeyResolver(keyResolver);
x509cert = keyInfo.getX509Certificate();

isValid = xmlSignature.checkSignatureValue(x509cert);

ColdFusion 9 doesn't have built in libraries to handle x509 validation, so two Java libraries were imported into our ColdFusion installation. ColdFusion 9没有内置库来处理x509验证,因此将两个Java库导入到我们的ColdFusion安装中。 These came from the Apache Santuario project. 这些来自Apache Santuario项目。 They are: 他们是:

  • serializer-2.7.1.jar 串行 - 2.7.1.jar
  • xmlsec-1.5.3.jar xmlsec-1.5.3.jar

The code runs just fine, but it always outputs "NO", the signature is not valid. 该代码运行得很好,但它始终输出“ NO”,签名无效。 I am certain that the assertion should valid properly. 我确信该断言应该正确有效。

I admit that I am just cargo coding here as I am not familiar enough with Java to truly understand what is going on here. 我承认我只是在这里进行货物编码,因为我对Java不够熟悉,无法真正理解这里发生的事情。

I've tried everything I can think of. 我已经尝试了所有我能想到的。 Can anyone offer any tips or ideas on what to check or what to modify to continue troubleshooting? 谁能提供有关检查或修改内容以继续进行故障排除的任何提示或想法?

== UPDATE 1 - Added SAML Assertion Example == ==更新1-添加了SAML声明示例==

This sample assertion from Salesforce.com is nearly identical in format to the one we are receiving. 来自Salesforce.com的此示例断言的格式几乎与我们收到的断言相同。 Yes our assertion does include a public key in it, just as this one does (though truncated here). 是的,我们的断言确实像其中一样包含一个公共密钥(尽管此处已被截断)。

<samlp:Response ID="_257f9d9e9fa14962c0803903a6ccad931245264310738" IssueInstant="2009-06-17T18:45:10.738Z" Version="2.0">
     <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
        https://www.salesforce.com
     </saml:Issuer>

     <samlp:Status>
        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
     </samlp:Status>

     <saml:Assertion ID="_3c39bc0fe7b13769cab2f6f45eba801b1245264310738" 
        IssueInstant="2009-06-17T18:45:10.738Z" Version="2.0">
        <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
           https://www.salesforce.com
        </saml:Issuer>

        <saml:Signature>
           <saml:SignedInfo>
              <saml:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
              <saml:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
              <saml:Reference URI="#_3c39bc0fe7b13769cab2f6f45eba801b1245264310738">
                 <saml:Transforms>
                    <saml:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                    <saml:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                       <ec:InclusiveNamespaces PrefixList="ds saml xs"/>
                    </saml:Transform>
                 </saml:Transforms>
                 <saml:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                 <saml:DigestValue>vzR9Hfp8d16576tEDeq/zhpmLoo=
                 </saml:DigestValue>
              </saml:Reference>
           </saml:SignedInfo>
           <saml:SignatureValue>
              AzID5hhJeJlG2llUDvZswNUrlrPtR7S37QYH2W+Un1n8c6kTC
              Xr/lihEKPcA2PZt86eBntFBVDWTRlh/W3yUgGOqQBJMFOVbhK
              M/CbLHbBUVT5TcxIqvsNvIFdjIGNkf1W0SBqRKZOJ6tzxCcLo
              9dXqAyAUkqDpX5+AyltwrdCPNmncUM4dtRPjI05CL1rRaGeyX
              3kkqOL8p0vjm0fazU5tCAJLbYuYgU1LivPSahWNcpvRSlCI4e
              Pn2oiVDyrcc4et12inPMTc2lGIWWWWJyHOPSiXRSkEAIwQVjf
              Qm5cpli44Pv8FCrdGWpEE0yXsPBvDkM9jIzwCYGG2fKaLBag==
           </saml:SignatureValue>
           <saml:KeyInfo>
              <saml:X509Data>
                 <saml:X509Certificate>
                    MIIEATCCAumgAwIBAgIBBTANBgkqhkiG9w0BAQ0FADCBgzELM
                    [Certificate truncated for readability...]
                 </saml:X509Certificate>
              </saml:X509Data>
           </saml:KeyInfo>
        </saml:Signature>

        <saml:Subject>
           <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">
              saml01@salesforce.com
           </saml:NameID>

           <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
           <saml:SubjectConfirmationData NotOnOrAfter="2009-06-17T18:50:10.738Z" 
              Recipient="https://login.www.salesforce.com"/>
           </saml:SubjectConfirmation>
        </saml:Subject>

        <saml:Conditions NotBefore="2009-06-17T18:45:10.738Z" 
           NotOnOrAfter="2009-06-17T18:50:10.738Z">

           <saml:AudienceRestriction>
              <saml:Audience>https://saml.salesforce.com</saml:Audience>
           </saml:AudienceRestriction>
        </saml:Conditions>

        <saml:AuthnStatement AuthnInstant="2009-06-17T18:45:10.738Z">
           <saml:AuthnContext>
              <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified
              </saml:AuthnContextClassRef>
           </saml:AuthnContext>
        </saml:AuthnStatement>

        <saml:AttributeStatement>

           <saml:Attribute Name="portal_id">
              <saml:AttributeValue xsi:type="xs:anyType">060D00000000SHZ
              </saml:AttributeValue>
           </saml:Attribute>

           <saml:Attribute Name="organization_id">
              <saml:AttributeValue xsi:type="xs:anyType">00DD0000000F7L5
              </saml:AttributeValue>
           </saml:Attribute>

           <saml:Attribute Name="ssostartpage" 
              NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">

              <saml:AttributeValue xsi:type="xs:anyType">
                 http://www.salesforce.com/security/saml/saml20-gen.jsp
              </saml:AttributeValue>
           </saml:Attribute>

           <saml:Attribute Name="logouturl" 
              NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">

              <saml:AttributeValue xsi:type="xs:string">
                 http://www.salesforce.com/security/del_auth/SsoLogoutPage.html
              </saml:AttributeValue>
           </saml:Attribute>
        </saml:AttributeStatement>
     </saml:Assertion>
  </samlp:Response>

== UPDATE 2 - Used keytool to add public key to java keystore == ==更新2-使用keytool将公共密钥添加到java keystore ==

Added public key to java keystore file "cacerts" using keytool command. 使用keytool命令向Java密钥库文件“ cacerts”添加了公共密钥。 I can see that the public key has now been added to our cacerts file and that the cert is marked as "trusted". 我可以看到公钥现已添加到我们的cacerts文件中,并且该证书被标记为“受信任”。

We were sent their public key in a *.pem file, so I used that to add their key to the keystore. 我们将他们的公钥发送到* .pem文件中,所以我用它来将他们的密钥添加到密钥库中。 I also tried converting the *.pem file to a *.der file and importing that. 我还尝试将* .pem文件转换为* .der文件并将其导入。 Both worked just fine. 两者都很好。 However, my code still returns "NO" for isValid. 但是,我的代码仍然为isValid返回“ NO”。 Ugh. 啊。

The public key in the *.pem file exactly matches the public key that comes in the SAML assertion. * .pem文件中的公钥与SAML断言中附带的公钥完全匹配。

If it is not validating or you get "Cannot resolve element with ID." 如果未通过验证,或者您收到“无法解析具有ID的元素”。 Add the third line below. 在下面添加第三行。 What is happening is the newer version of Apache Santuario no longer assumes the IdAttribute is "ID". 发生的事情是Apache Santuario的较新版本不再假定IdAttribute为“ ID”。 You need to manually set it. 您需要手动设置。

xmlResponse = getHttpRequestData().content.Trim();
docElement = XmlParse(variables.xmlResponse);
docElement.setIdAttribute("ID",true); //Add this line

Since you mention Apache Santuario, here's a Java code sample from that project that involves validating an XML digital signature. 既然您提到了Apache Santuario,那么这里是该项目的Java代码示例 ,其中涉及验证XML数字签名。

That sample uses the public key from the X509Certificate instead of the cert itself. 该示例使用来自X509Certificate公钥而不是证书本身。 Your code sample seems to be using the cert itself: 您的代码示例似乎正在使用cert本身:

keyInfo = xmlSignature.getKeyInfo();
X509CertificateResolverCN = "org.apache.xml.security.keys.keyresolver.implementations.X509CertificateResolver";
keyResolver = CreateObject("Java", X509CertificateResolverCN).init();
keyInfo.registerInternalKeyResolver(keyResolver);
x509cert = keyInfo.getX509Certificate();

isValid = xmlSignature.checkSignatureValue(x509cert);

How about adjusting this to use the java.security.PublicKey from the X509Certificate : 如何调整它以使用X509Certificatejava.security.PublicKey

keyInfo = xmlSignature.getKeyInfo();
X509CertificateResolverCN = "org.apache.xml.security.keys.keyresolver.implementations.X509CertificateResolver";
keyResolver = CreateObject("Java", X509CertificateResolverCN).init();
keyInfo.registerInternalKeyResolver(keyResolver);
x509cert = keyInfo.getX509Certificate();
publicKey = x509cert.getPublicKey()

isValid = xmlSignature.checkSignatureValue(publicKey);

Disclaimer: I've never written a line of CF in my life, so if it works but there are adjustments to make please comment and I'll adjust it. 免责声明:我一生中从未写过CF线,因此,如果它有效,但需要进行一些调整,请发表评论,我会进行调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM