gpt4 book ai didi

c# - WSHttpBinding TransportWithMessageCredential SecurityMode 改变请求

转载 作者:行者123 更新时间:2023-11-30 12:56:23 24 4
gpt4 key购买 nike

我正在努力处理 WCF 绑定(bind)配置。我添加了第三方服务作为对我项目的引用。我得到了一些规范。

我需要使用 SOAP v1.2 所以我想我需要 WSHttpBinding 它将是 https 所以我需要 安全模式.Transport

像这样:

var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
var client = new MyClient(binding, addr);
var result = client.Method(new MyObject());

它会生成此请求正文。

 <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"      
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<S:Header>
<wsa:MessageID>
uuid:6B29FC40-CA47-1067-B31D-00DD010662DA
</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>example</wsa:Address>
</wsa:ReplyTo>
<wsa:To>example</wsa:To>
<wsa:Action>example</wsa:Action>
</S:Header>
<S:Body>
<MyObject>...</MyObject>
</S:Body>
</S:Envelope>

根据提供的规范,我需要在 header 中包含 Security 元素以及 UsernameTokenTimestamp。正是使用 BasicHttpBindingBasicHttpSecurityMode.TransportWithMessageCredential

我会得到什么

当我尝试使用 WSHttpBinding 设置 TransportWithMessageCredential 模式时,请求主体发生巨大变化。

binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var client = new MyClient(binding, addr);
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "123456";
var result = client.Method(new MyObject());
 <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"      
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<S:Header>
<wsa:MessageID>
uuid:b633067e-9a9e-4216-b036-4afa3aca161e
</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>example</wsa:To>
<wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</wsa:Action>
<o:Security s:mustUnderstand=1 xmlns:o=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd>
<u:Timestamp>...<u:Timestamp>
<o:UsernameToken>
<o:Username>...</o:Username>
<o:Password>...</o:Password>
</o:UsernameToken>
</o:Security>
</S:Header>
<S:Body>
<t:RequestSecurityToken>...</t:RequestSecurityToken>
</S:Body>
</S:Envelope>

现在我的安全部分是正确的,但是所有寻址部分都是错误的,正文也是如此。我该怎么办?

我期待(并且我需要)这样的东西:

 <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"      
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<S:Header>
<wsa:MessageID>
uuid:6B29FC40-CA47-1067-B31D-00DD010662DA
</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>example</wsa:Address>
</wsa:ReplyTo>
<wsa:To>example</wsa:To>
<wsa:Action>example</wsa:Action>
<o:Security s:mustUnderstand=1 xmlns:o=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd>
<u:Timestamp>...<u:Timestamp>
<o:UsernameToken>
<o:Username>...</o:Username>
<o:Password>...</o:Password>
</o:UsernameToken>
</o:Security>
</S:Header>
<S:Body>
<MyObject>...</MyObject>
</S:Body>
</S:Envelope>

最佳答案

您发布的第二个数据包不是 WCF 调用请求,而是安全通道设置的一部分。这是将用 RequestSecurityTokenResponse 应答的 RequestSecurityToken 数据包。之后,如果 channel 设置正确,将发送与您在第一个代码段中发布的相同的方法调用数据包。您可以在服务跟踪查看器中看到此数据包序列:

enter image description here

您要解决的实际问题是什么?您的 WCF 调用是否失败?如果是这样,请提供异常详细信息。最可能的原因是 WCF 配置或身份验证错误。

如果您努力避免这些协商数据包,请查看此 answer这显示了如何将 SecurityMode 切换到 Message 并将 NegotiateServiceCredential 选项设置为 false

更新:

这部分与要求修复请求的地址部分的问题更新有关。

要手动设置 wsa:ReplyTo header ,您需要设置 ReplyTo OperationContext.OutgoingMessageHeaders的属性(property),像这样:

using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageHeaders.ReplyTo = new EndpointAddress("http://someclient/callback");
var request = client.Method(new MyObject());
}

查看此 answer了解更多详情。

关于c# - WSHttpBinding TransportWithMessageCredential SecurityMode 改变请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41403740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com