79766193

Date: 2025-09-16 11:52:01
Score: 0.5
Natty:
Report link

Thank you so much @joe-sindoni. I had been struggling for hours with WCF to get it working with WS Security. In my case, I had to make a few modifications (with Copilot's help) so the server would validate my signature:

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
    // Add the ws-Security header
    request.Headers.Add(new WsSecurityHeader());

    // Get the entire message as an xml doc, so we can sign the body.
    var xml = GetMessageAsString(request);

    XmlDocument doc = new XmlDocument();
    doc.PreserveWhitespace = false;
    doc.LoadXml(xml);

    XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
    nsmgr.AddNamespace("soapenv", WsSecurityHeader.SoapEnvelopeNamespace);
    nsmgr.AddNamespace("wsse", WsSecurityHeader.WsseNamespace);
    nsmgr.AddNamespace("wsu", WsSecurityHeader.WsseUtilityNamespaceUrl);
    nsmgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");

    // The Body is the element we want to sign.
    var body = doc.SelectSingleNode("//soapenv:Body", nsmgr) as XmlElement;

    // Add the Id attribute to the Body, for the Reference element URI
    var id = doc.CreateAttribute("wsu", "Id", WsSecurityHeader.WsseUtilityNamespaceUrl);
    id.Value = BodyIdentifier;
    body.Attributes.Append(id);

    // Get the Security header
    XmlNode securityHeader = doc.SelectSingleNode("//soapenv:Envelope/soapenv:Header/wsse:Security", nsmgr);

    // Add BinarySecurityToken
    string certId = "X509-" + Guid.NewGuid().ToString();
    XmlElement binarySecurityToken = doc.CreateElement("wsse", "BinarySecurityToken", WsSecurityHeader.WsseNamespace);
    binarySecurityToken.SetAttribute("Id", WsSecurityHeader.WsseUtilityNamespaceUrl, certId);
    binarySecurityToken.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
    binarySecurityToken.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
    binarySecurityToken.InnerText = Convert.ToBase64String(X509Certificate.GetRawCertData());
    securityHeader.AppendChild(binarySecurityToken);

    var signedXml = new SignedXmlWithUriFix(doc);
    signedXml.SigningKey = X509Certificate.PrivateKey;
    signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;
    signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

    // Add the X509 certificate info to the KeyInfo section
    var keyInfo = new KeyInfo();
    
    // Create SecurityTokenReference to refer to the BinarySecurityToken
    XmlElement securityTokenReference = doc.CreateElement("wsse", "SecurityTokenReference", WsSecurityHeader.WsseNamespace);
    XmlElement reference = doc.CreateElement("wsse", "Reference", WsSecurityHeader.WsseNamespace);
    reference.SetAttribute("URI", $"#{certId}");
    reference.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
    securityTokenReference.AppendChild(reference);
    
    // Add the SecurityTokenReference to KeyInfo
    KeyInfoNode keyInfoNode = new KeyInfoNode(securityTokenReference);
    keyInfo.AddClause(keyInfoNode);
    
    signedXml.KeyInfo = keyInfo;

    // Add the reference to the SignedXml object
    Reference xmlReference = new Reference($"#{BodyIdentifier}");
    xmlReference.DigestMethod = SignedXml.XmlDsigSHA1Url;
    
    // Add transform
    xmlReference.AddTransform(new XmlDsigExcC14NTransform());
    
    signedXml.AddReference(xmlReference);

    // Compute the signature
    signedXml.ComputeSignature();

    // Get the Signature element and append to security header
    XmlElement xmlDigitalSignature = signedXml.GetXml();
    securityHeader.AppendChild(doc.ImportNode(xmlDigitalSignature, true));

    // Generate a new message from our XmlDocument
    var newMessage = CreateMessageFromXmlDocument(request, doc);
    request = newMessage;

    return null;
}
Reasons:
  • Blacklisted phrase (0.5): Thank you
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @joe-sindoni
  • Low reputation (0.5):
Posted by: rasputino