我一直在研究一个WCF服务,它将返回一个Base64编码的字符串,实际上是一个完整的SAML响应XML文档。由于此信息将传递给供应商,因此我必须满足他们对SAML文档的外观和编码方式的要求。我无法获得满足其要求的输出。
我知道WCF和WIF一起应该帮助我。我最初使用WIF构建服务来创建SAML断言(令牌)和其他C#代码以生成最终的SAML文档。除了< EncryptedData>之外,所有这些都可以满足供应商的要求。文档的节点。本节使用AES256和RSAOAEP,但供应商需要AES128和RSA15。因此,我正在寻求解决方案。任何帮助将不胜感激。
这是一个漫步。
该服务接受GUID,该GUID用于调用数据库并返回字段。然后使用它们:
DataTable userData = GetDataForUser(userId);
List<Claim> claims = new List<Claim>()
{
new Claim("ClientId", "NameOfClient")
};
foreach (DataRow row in userData.Rows)
{
string memberId = row["MemberId"].ToString().Trim();
string firstName = row["FirstName"].ToString().Trim();
string lastName = row["LastName"].ToString().Trim();
DateTime dob = Convert.ToDateTime(row["DateOfBirth"], CultureInfo.InvariantCulture);
claims.Add(new Claim("MemberId", memberId));
claims.Add(new Claim("FirstName", firstName));
claims.Add(new Claim("LastName", lastName));
claims.Add(new Claim("DOB", dob.ToString("MM/dd/yyyy")));
}
return claims;
然后我创建一个像这样的SecurityTokenDescriptor:
SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor();
将声明添加到描述符中,如下所示:
descriptor.Subject = new ClaimsIdentity(claims);
指示描述符加密令牌,如下所示:
descriptor.EncryptingCredentials = GetEncryptingCredentials();
并且GetEncryptingCredentials()例程如下所示:
private EncryptedKeyEncryptingCredentials GetEncryptingCredentials()
{
// Get the Encrypting Certificate
X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, "<<certificate stuff here >>", true);
EncryptedKeyEncryptingCredentials encryptingCreds = new EncryptedKeyEncryptingCredentials(encryptCert);
return encryptingCreds;
}
所有这些都会生成一个令牌,当写入文件时会给我这个:
<EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<xenc:EncryptedData Id="_16584ace-9f3e-4352-9fc9-f6db8b2e925c" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
</e:EncryptionMethod>
<KeyInfo>
<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<X509Data>
<X509IssuerSerial>
<X509IssuerName><!-- value --></X509IssuerName>
<X509SerialNumber><!-- value --></X509SerialNumber>
</X509IssuerSerial>
</X509Data>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue><!-- value -->CipherValue>
</e:CipherData>
</e:EncryptedKey>
</KeyInfo>
<xenc:CipherData><xenc:CipherValue><!-- value --></xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</EncryptedAssertion>
很好,对吗?不。供应商需要&lt; EncryptedData&gt;具有以下子节点的部分:
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
他们需要&lt; KeyInfo&gt;&lt; EncryptedKey&gt;部分显示这个:
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
我在GetEncryptingCredentials()例程中尝试了我能想到的所有组合。什么都没有产生预期的结果。我收到的最有希望的错误消息如下:
ID4178:EncryptingCredentials 提供在 SecurityTokenDescriptor用于 不对称密钥。你必须使用 EncryptedKeyEncryptingCredentials to 加密令牌。
有人有建议吗?不要害怕告诉我从头开始。没关系。我只需要让它发挥作用。
提前致谢。
答案 0 :(得分:6)
我找到了一个有效的解决方案。至少,它根据我的需要生成XML,并且供应商已经表示他们可以使用我发送的内容。
我稍微重写了GetEncryptingCredentials()例程。它现在看起来像这样:
private EncryptingCredentials GetEncryptingCredentials()
{
string keyWrapAlgorithm = SecurityAlgorithms.RsaV15KeyWrap; //"http://www.w3.org/2001/04/xmlenc#aes256-cbc";
string encryptionAlgorithm = SecurityAlgorithms.Aes128Encryption; //"http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p";
int keySize = 128;
X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, _settings.EncryptingCredentials, true);
EncryptingCredentials encryptingCredentials = new EncryptedKeyEncryptingCredentials(encryptCert, keyWrapAlgorithm, keySize, encryptionAlgorithm);
return encryptingCredentials;
}
我想我会让每个人都知道并关闭它。