如何添加变换算法(“envelope-signature”)
Posted
技术标签:
【中文标题】如何添加变换算法(“envelope-signature”)【英文标题】:How to add transform algorithm ("enveloped-signature") 【发布时间】:2021-03-28 02:58:10 【问题描述】:我一直在调用需要“封装签名”作为转换算法的肥皂服务。我得到“xml-exc-c14n#”。我正在使用自定义绑定来初始化 WCF 请求的客户端。
更新: 在上面的示例中,我尝试不使用消息检查器。所以我尝试了两种方法。 1. 使用 WCF 调用,但我无法将转换算法更改为“包络签名”。 2. 我尝试使用 Inspector 创建签名的 XML 文档并将其添加到请求消息中。就像在这个例子中解释的那样Message inspectors- WCF call 我都失败了。
以下是我在没有 Inspector 的情况下用于 WCF 调用的代码
var b = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
sec.EndpointSupportingTokenParameters.Signed.Add(new UserNameSecurityTokenParameters());
sec.MessageSecurityVersion =
MessageSecurityVersion.
WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12;
sec.IncludeTimestamp = false;
sec.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;
sec.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic256Sha256;
X509SecurityTokenParameters x509Params = new X509SecurityTokenParameters
X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial,
RequireDerivedKeys = false,
InclusionMode = SecurityTokenInclusionMode.Once,
ReferenceStyle = SecurityTokenReferenceStyle.Internal
;
((AsymmetricSecurityBindingElement)sec).InitiatorTokenParameters = x509Params;
b.Elements.Add(sec);
b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
b.Elements.Add(new HttpsTransportBindingElement() );
如果您有任何想法,请帮助我。
【问题讨论】:
如果您的问题是对请求消息进行操作,可以参考:docs.microsoft.com/en-us/dotnet/framework/wcf/samples/… @TheobaldDu 是的,这也是关于更改消息的。所以我确实使用了这个事件 BeforeSendRequest。但是我尝试用来替换现有请求(消息)的签名 xml 并未完全复制。因此,当我创建消息时,签名的 xml 字符串会发生变化。 @TheobaldDu 在上面的例子中,我在没有检查员的情况下尝试。所以我尝试了两种方式。 1. 使用 wcf 调用,但我无法将转换算法更改为“包络签名”。 2. 我尝试使用 Inspector 创建签名的 xml 文档并将其添加到请求消息中。我都失败了。 【参考方案1】:在客户端,通过实现IClientMessageInspector接口来拦截SOAP消息。
public class ClientMessageLogger : IClientMessageInspector
public object AfterReceiveRequest(ref Message reply, object correlationState)
MessageHeader header = MessageHeader.CreateHeader("UserAgent", "http://User", "User1");
reply.Headers.Add(header);
return null;
public void BeforeSendRequest(ref Message request, IClientChannel channel)
MessageHeader header1 = MessageHeader.CreateHeader("Testreply", "http://Test", "Test");
request.Headers.Add(header1);
[AttributeUsage(AttributeTargets.Interface)]
public class CustomBehavior : Attribute, IContractBehavior
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
return;
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
return;
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
dispatchRuntime.MessageInspectors.Add(new CustomMessageInspector());
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
return;
然后,将 CustContractBehavior 功能应用到服务接口。
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
[CustomBehavior]
public interface IDemo
客户端向服务器发送请求时,会调用BeforeSendRequest,客户端收到服务器回复消息时,会调用AfterReceiveReply。
【讨论】:
您好,我正在实施这个。对不起,如果我不清楚。但是我在这里面临的问题是我需要替换整个消息而不是单个标题。因为它是一个签名的 XML,其中包含带有证书的安全标头和所有内容。我可以单独签署 xml 正文(有效的签名 xml 作为字符串)。现在我想用它作为请求消息。但是当我尝试从该签名的 xml 中创建一条消息时,它会发生变化并且不再是有效的 xml。 可以,消息拦截器只能修改消息头,不允许修改消息体,因为消息体的结构是由服务契约的定义决定的,而修改会导致消息内容验证失败。如果要修改消息,MessageFormatter 允许自定义 SOAP 消息。以上是关于如何添加变换算法(“envelope-signature”)的主要内容,如果未能解决你的问题,请参考以下文章