Vid*_*d L 4 salesforce x509certificate saml-2.0 component-space
我们的 IdP 是 Salesforce.com 组织。SP 是第三方.Net 应用程序。在开发过程中,第 3 方报告称他们无法验证发送的 SAML 响应。
我们决定尝试使用ComponentSpace来验证 SAML 响应。以下是我们尝试过的:
// Load the certificate from the file: certInFile
// Load the SAML in an XMLElement: samlXml
// Retrieve the certificate from the SAML: certInSaml
Console.WriteLine("SAML is valid ? " + SAMLResponse.IsValid(samlXml));
Console.WriteLine("Is SAML signed? " + SAMLMessageSignature.IsSigned(samlXml));
Console.WriteLine("Certificate found in SAML is same as certificate file? " + certInFile.Equals(certInSaml));
Console.WriteLine("Validated SAML with certificate found in SAML" + SAMLMessageSignature.Verify(samlXml, certInSaml));
Console.WriteLine("Validated SAML with certificate file" + SAMLMessageSignature.Verify(samlXml, certInFile));
Run Code Online (Sandbox Code Playgroud)
除了最后两个之外,我对上述所有内容都非常了解。所以:
从 3,4 我们可以得出结论,Salesforce 正在签名,但使用不同的证书,但在响应中发送了错误的公钥?!
编辑:示例 SAML 位于http://pastebin.com/J8FTxnhJ
我缺少什么?
I know this is an old post, but I ran into the same issue and was dissatisfied with the non-answer. For those who are running into this issue and find this page from an internet search as being one of the only results for failed signature validation of Salesforce SAML using ComponentSpace, the issue likely isn't within SAML signature verification itself, but how you're decoding the base-64 encoded SAML Response payload.
Note that the SAMLServiceProvider.ReceiveSSO()
method that takes an HttpRequest
does not suffer from this issue. I've found that it's specifically when manually decoding the payload that can trigger this issue, depending on the format of the XML when the IdP signed the response.
Since this is an older post and the pastebin link is long gone, let's assume that the original code might have looked like the following. (Also assuming that the X.509 cert is embedded in the payload, but the fix is ultimately the same.)
var str = Encoding.UTF8.GetString(Convert.FromBase64String(samlResponse));
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(str);
var xcert = SAMLMessageSignature.GetCertificate(xdoc.DocumentElement);
var isSigned = SAMLMessageSignature.IsSigned(xdoc.DocumentElement);
var isValid = SAMLResponse.IsValid(xdoc.DocumentElement);
var isVerified = SAMLMessageSignature.Verify(xdoc.DocumentElement);
Run Code Online (Sandbox Code Playgroud)
In the case of Salesforce (and likely others), xcert will be non-null, isSigned and isValid set to true, but isVerified will be false. The simple, elusive fix for the above code? xdoc.PreserveWhitespace = true;
The reason is because the signature is generated based on the raw XML structure (or some sub-section of it). If the IdP has whitespaces in their original SAML XML it is included in the signature generation, even if whitespaces can normally be ignored in an XML. This is why IsValid will still return true, while the signature verification fails.
One last handy note, buried in ComponentSpace's sample code, the full safe XmlDocument conversion is:
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore;
xmlReaderSettings.XmlResolver = null;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.XmlResolver = null;
using (XmlReader xmlReader = XmlReader.Create(new StreamReader(fileName), xmlReaderSettings))
{
xmlDocument.Load(xmlReader);
}
Run Code Online (Sandbox Code Playgroud)
For our scenario, we didn't need to include the DtdProcessing.Ignore
in the extra step of using XmlReaderSettings
, but including it in this solution to cover all use cases.
归档时间: |
|
查看次数: |
36890 次 |
最近记录: |