我正在创建一个SAML身份提供商,我们的服务提供商正在使用第三方工具Component Space来完成他们的工作。我开发的身份提供程序从用户获取登录凭据,并在我们的活动目录联合服务器上验证该用户。如果用户有效,那么我创建一个SAMLResponse,使用X509Certificate签名并将其发布到我从SAMLRequest收到的AssertionConsumerServiceURL。现在,我需要验证SAMLRequest是否来自有效的服务提供商,并且之间没有进行修改。
最初服务提供商正在使用HTTP重定向绑定并在查询字符串中发送SAMLRequest,SigAlg和Signature,我在下面的代码中尝试验证签名,但它总是返回false。
public bool VerifyHashDynamic(string Signature, string request)
{
bool isVerified = false;
X509Certificate2 x509 = new X509Certificate2(Server.MapPath(".") + @"\X509Certificate\SP.cer", "password");
byte[] signature = Base64DecodeArray(Signature);
byte[] signedData = Base64DecodeArray(request);
RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)x509.PublicKey.Key;
SHA256Managed hash = new SHA256Managed();
byte[] hashedData;
bool dataOK = rsaCSP.VerifyData(signedData, CryptoConfig.MapNameToOID("SHA256"), signature);
hashedData = hash.ComputeHash(signedData);
isVerified = rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA256"), signature);
return isVerified;
}
上面的代码是否有问题,允许签名验证?
为了使其以另一种方式工作,我要求我们的服务提供商发送带有嵌入式签名的AuthNRequest(HTTP-POST绑定)。对于发布的AuthnRequest的签名验证,我尝试了XMLDocument验证,这里是代码:
public Boolean VerifyXml()
{
string mystr = string.Empty;
mystr = "9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIiBBbGxvd0NyZWF0ZT0idHJ1ZSIgLz48L3NhbWxwOkF1dGhuUmVxdWVzdD4=";
mystr = GetXmlFromSAML(mystr, false);
mystr = mystr.TrimEnd().TrimStart();
X509Certificate2 myCert = new X509Certificate2(Server.MapPath(".") + @"\X509Certificate\SP.cer");
XmlDocument Doc = new XmlDocument();
Doc.PreserveWhitespace = false;
Doc.XmlResolver = null;
Doc.LoadXml(mystr);
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(Doc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
throw new CryptographicException("Verification failed: No Signature was found in the document.");
}
// This example only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count >= 2)
{
throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(myCert, false);
}
使用上述验证码,我得到异常“无法为提供的签名算法创建SignatureDescription”。我不确定如何让这个签名验证工作。
是否真的可以使用X509Certificate手动验证SAMLRequest签名?是否可以在没有AuthnRequest签名验证的情况下进行登录检查?
上个月我一直在谷歌搜索所有这些,但没有运气。非常感谢任何帮助。