发送请求前需要在我的WCF客户端中操作SOAP头的帮助吗
我有一个独特的需求,需要在请求中向外部供应商发送高度定制的soap头。我的WCF客户端与他们的web服务交互的唯一方式是使用用户名令牌和消息签名的组合来对整个信封进行签名(请参阅下面供应商提供的soap头)发送请求前需要在我的WCF客户端中操作SOAP头的帮助吗,wcf,c#-4.0,c#-3.0,wcf-security,wcf-client,Wcf,C# 4.0,C# 3.0,Wcf Security,Wcf Client,我有一个独特的需求,需要在请求中向外部供应商发送高度定制的soap头。我的WCF客户端与他们的web服务交互的唯一方式是使用用户名令牌和消息签名的组合来对整个信封进行签名(请参阅下面供应商提供的soap头) 是否有更好的实施方法?请提供样品。。这是我第一次向供应商发送自定义SOAP头,这对我来说很复杂。时间不够。请帮忙 查看下面的文章,它向您展示了一个如何实现IClientMessageInspector的示例,IClientMessageInspector可以更改消息并插入自定义头 首先,您
是否有更好的实施方法?请提供样品。。这是我第一次向供应商发送自定义SOAP头,这对我来说很复杂。时间不够。请帮忙 查看下面的文章,它向您展示了一个如何实现IClientMessageInspector的示例,IClientMessageInspector可以更改消息并插入自定义头 首先,您需要定义一个自定义头来表示SOAP头的内容。为此,请创建自己的类后代 创建一个在发送请求之前(在发送请求之前)注入自定义头的实现 现在,您需要将自定义消息检查器添加到WCF管道,但您已经涵盖了这一部分 BeforeSendRequest(ref Message request,IClientChannel通道)的Message参数可用于使用(ToString(),GetBody(),…等)的方法之一读取SOAP消息 要获取消息正文,请使用GetReaderAtBodyContents()方法,该方法返回一个对象。使用此XML读取器以字符串形式检索正文 例如:
using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
{
string content = reader.ReadOuterXml();
//...
}
我正在使用BeforeSendRequest方法,我需要他的帮助>>>>>>>>1。如何提取SOAP请求的主体并将其转换为字符串,并将其作为输入传递给我的“CreateX509SoapEnvelope”方法?2.在方法中将标题缝合在一起后,“CreateX509SoapEnvelope”的输出也是一个字符串。现在我需要获取字符串并将其转换,以便使用request.WriteHeader()方法。请检查我的密码,更新我的答案。请检查我添加的关于GetReaderAtombodyContents()方法的部分。@wcfvemi:这有用吗?我正试图做同样的事情,却被卡住了(
class x509_Authentication
{
public string CreateX509SoapEnvelope(string xml)
{
string soapXML;
soapXML = "<soapenv:Envelope xmlns:bsvc=\"urn:com.workday/bsvc\"
xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">";
soapXML += "<soapenv:Header>\n";
// Add security block for X.509 certificate
soapXML = "<wsse:Security xmlns:wsse=\"http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">";
soapXML += "<wsse:UsernameToken wsu:Id=\"UsernameToken-20\"
xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd\">";
soapXML += "<wsse:Username>Cert509User</wsse:Username>";
soapXML += "</wsse:UsernameToken>";
soapXML += "</wsse:Security>";
soapXML += "</soapenv:Header>" + xml + "</soapenv:Envelope>";
// Sign Envelope
soapXML = CreateSignatureBlock(soapXML, "wsse:Security");
// Verify that the XML was signed properly
VerifySignedXml(soapXML);
return soapXML;
}
public string CreateSignatureBlock(string xml, string sParentSignatureTagName)
{
try
{
string certificatePath="C:\\Users\\user3434\\Desktop\\certfolder\\cert.p12";
//load xml into a dom
XmlDocument xd = new XmlDocument();
xd.LoadXml(xml);
// Set Certificate
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new X509Certificate2(certificatePath, "changeit");
//System.Security.Cryptography.X509Certificates.X509Certificate2 cert = x509_Authentication.GetCertificateFromStore();
SignedXml signedXml = new SignedXml(xd);
signedXml.SigningKey = cert.PrivateKey;
// Create a new KeyInfo object.
KeyInfo keyInfo = new KeyInfo();
keyInfo.Id = "";
// Load the certificate into a KeyInfoX509Data object
// and add it to the KeyInfo object.
KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
keyInfoData.AddCertificate(cert);
keyInfo.AddClause(keyInfoData);
// Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyInfo;
// Need to use External Canonicalization method.
signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Add the Signature Id
signedXml.Signature.Id = "";
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the Signature element to the XML document. It will find the element after which we want to insert the signature
XmlNodeList nodeList = xd.GetElementsByTagName(sParentSignatureTagName);
if (nodeList.Count > 0)
{
XmlNode headerNode = nodeList[0];
headerNode.AppendChild(xd.ImportNode(xmlDigitalSignature, true));
}
return xd.InnerXml;
}
catch
{
return xml;
}
}
public void VerifySignedXml(String xml)
{
// Create a new XML document.
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.LoadXml(xml);
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(xmlDocument);
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
Reference reference = new Reference();
reference.AddTransform(env);
signedXml.AddReference(reference);
// Find the "Signature" node and create a new XmlNodeList object.
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
// Load the signature node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
//if (!signedXml.CheckSignature(cert,true))
//if (!signedXml.CheckSignature(new X509Certificate2(certificatePath, "sdfdf"), true))
//{
// log.Error("Invalid Signature");
//}
}
}
public string RequestMessage { get; set; }
public string ResponseMessage { get; set; }
object IClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
{
**HOW TO EXTRACT SOAPBODY FROM “.ServiceModel.Channels.Message request” OBJECT and CONVERT THAT TO STRING ??????????**
x509_Authentication x509 = new x509_Authentication();
this.ResponseMessage = x509.CreateX509SoapEnvelope(SOAP Body);
**TAKE THE RESPONSE MESSAGE AND CONVERT BACK TO “.ServiceModel.Channels.Message request” AND SEND THE REQUEST ALONG???????????**
return null;
}
public class MyHeader : MessageHeader
{
//...
}
public class CustomMessageInspector : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
request = buffer.CreateMessage();
request.Headers.Add(new MyHeader());
return null;
}
//...
}
using (XmlDictionaryReader reader = message.GetReaderAtBodyContents())
{
string content = reader.ReadOuterXml();
//...
}