Я пытаюсь реализовать единый вход с использованием SAML. Идентификатор отправил мне пример запроса, как показано ниже:
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
AssertionConsumerServiceURL="https://client1.com/MyBank1/ReceiveSAMLResponse"
Destination=" https://tawtheeq.sa/identity-gateway/ReceiveSAMLRequest"
ForceAuthn="false" ID="9eff699e-6e2c-487c-940f-1f67c226f423" IsPassive="false"
IssueInstant="2018-02-05T07:49:14.992Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> https://client1.com/</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
...
</ds:SignedInfo>
<ds:SignatureValue>
tKSzhWGSv...FPbhwPQ==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDZz...tlak4=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<samlp:NameIDPolicy AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" />
<samlp:RequestedAuthnContext Comparison="exact">
<saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>
Они также предоставили мне свой файл сертификата .cer для проверки подписи в ответе, файл .cer, который я могу использовать в качестве нашего файла .cer, пароля хранилища ключей и псевдонима и файла keystore.jks.
Я создал образец веб-проекта для тестирования. Пустую страницу, нажав на эту кнопку одной кнопкой. Я создаю объект X509Certificate2, используя наш файл (SP) .cer и создаю testXML, затем подписываю и, наконец, отправляю запрос на URL. Ниже приведен код, который я использую.
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SendRequest_Click(object sender, EventArgs e)
{
string RequestURL = "https://tawtheeq.sa:8443/identity-gateway-test/ReceiveSAMLRequest";
var certificate = new X509Certificate2(@"my-bank1-public.cer");
XmlDocument xml = CreateSomeXml("textXML");
var guid = Guid.NewGuid();
var signedXml = SignDoc(xml, certificate, guid.ToString(), guid.ToString());
PostXMLData(RequestURL, signedXml.ToString());
}
public void PostXMLData(string destinationUrl, string requestXml)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);
byte[] bytes;
bytes = System.Text.Encoding.ASCII.GetBytes(requestXml);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = bytes.Length;
request.Method = "POST";
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
//Response.RedirectPermanent(response.ResponseUri.);
//if (response.StatusCode == HttpStatusCode.OK)
//{
// Stream responseStream = response.GetResponseStream();
// string responseStr = new StreamReader(responseStream).ReadToEnd();
// return responseStr;
//}
}
public static XmlElement SignDoc(XmlDocument doc, X509Certificate2 cert2, string referenceId, string referenceValue)
{
SamlSignedXml sig = new SamlSignedXml(doc, referenceId);
// Add the key to the SignedXml xmlDocument.
sig.SigningKey = cert2.PrivateKey;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = String.Empty;
reference.Uri = "#" + referenceValue;
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new
XmlDsigEnvelopedSignatureTransform();
XmlDsigC14NTransform env2 = new XmlDsigC14NTransform();
reference.AddTransform(env);
reference.AddTransform(env2);
// Add the reference to the SignedXml object.
sig.AddReference(reference);
// Add an RSAKeyValue KeyInfo
// (optional; helps recipient find key to validate).
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyData = new KeyInfoX509Data(cert2);
keyInfo.AddClause(keyData);
sig.KeyInfo = keyInfo;
// Compute the signature.
sig.ComputeSignature();
// Get the XML representation of the signature
// and save it to an XmlElement object.
XmlElement xmlDigitalSignature = sig.GetXml();
return xmlDigitalSignature;
}
public static XmlDocument CreateSomeXml(string FileName)
{
// Create a new XmlDocument object.
XmlDocument document = new XmlDocument();
// Create a new XmlNode object.
XmlNode node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples");
// Add some text to the node.
node.InnerText = "Example text to be signed.";
// Append the node to the document.
document.AppendChild(node);
// Save the XML document to the file name specified.
XmlTextWriter xmltw = new XmlTextWriter(FileName, new UTF8Encoding(false));
document.WriteTo(xmltw);
xmltw.Close();
return document;
}
}
public class SamlSignedXml : SignedXml
{
private string _referenceAttributeId = "";
public SamlSignedXml(XmlDocument document,
string referenceAttributeId) : base(document)
{
_referenceAttributeId = referenceAttributeId;
}
public override XmlElement GetIdElement(
XmlDocument document, string idValue)
{
return (XmlElement)
document.SelectSingleNode(
string.Format("//*[@{0}='{1}']",
_referenceAttributeId, idValue));
}
}
Подписанный XML из кода не является правильным, и он не работает, когда я пытаюсь опубликовать файл:
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-
20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-
signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>zSI5ZAMmQ+8u7R2rP7aAPT6nNQw=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#">EncryptedKey</SignatureValue>
Примечание: Я удалил зашифрованный ключ из подписанного xml.
Мои вопросы:
- Правильно, почему для этой интеграции я впервые работаю с SAML SSO.
- Какая польза от Keystore в этой ситуации.
- Буду признателен, если вы поделитесь со мной какой-нибудь полезной статьей на эту тему.
Спасибо