我想使用WCF连接到服务Web服务,该服务使用证书进行身份验证是消息级别。
我目前在App.config中有这个配置:
<basicHttpBinding>
<binding name="SomeServiceHttpsBinding">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
,此绑定在服务的端点中指定。
连接正常,服务器发送,接受并响应请求,但服务器的响应中不包含任何安全标头(我使用代理调试器检查了实际响应)。所以我得到了这个例外:
未处理的类型异常 发生'System.ServiceModel.Security.MessageSecurityException' mscorlib.dll中
其他信息:安全处理器无法找到 消息中的安全标头。这可能是因为消息是 一个不安全的错误或因为它之间存在绑定不匹配 沟通各方。如果配置了服务,则会发生这种情况 为了安全起见,客户端没有使用安全性。
我发现我必须将绑定类型从<basicHttpBinding>
更改为<customBinding>
,并将属性enableUnsecuredResponse="true"
添加到其中以解决此问题。但它有很多复杂的选项让我困惑,我不知道我怎么能在这里做同样的事情。
现在问题是,如何以<customBinding>
格式编写上述设置的等效内容,以便我也可以使用enableUnsecuredResponse
?
答案 0 :(得分:1)
这是我解决问题的方法。希望这也有助于其他人。
<customBinding>
<binding name="SthHttpsBinding">
<security enableUnsecuredResponse="true" authenticationMode="CertificateOverTransport">
</security>
<httpsTransport maxBufferSize="1048576"
maxReceivedMessageSize="1048576" maxBufferPoolSize="10485760"></httpsTransport>
</binding>
</customBinding>
答案 1 :(得分:0)
我找到了解决我几乎类似问题的另一种方法(由代码完成,而不是通过配置和BasicHttpsBinding)。这是一个基于带有用户名/密码的SOAP消息的解决方案(为了使样本易于测试)
private static ChannelFactory<T> CreateSecureChannel<T>(string url, string username, string password)
{
var binding = new BasicHttpsBinding
{
MessageEncoding = WSMessageEncoding.Text,
UseDefaultWebProxy = true,
BypassProxyOnLocal = false,
Security =
{
Mode = BasicHttpsSecurityMode.TransportWithMessageCredential,
Transport =
{
ClientCredentialType = HttpClientCredentialType.None,
ProxyCredentialType = HttpProxyCredentialType.None
},
Message =
{
ClientCredentialType = BasicHttpMessageCredentialType.UserName,
AlgorithmSuite = SecurityAlgorithmSuite.Default
}
}
};
var channel = new ChannelFactory<T>(binding, new EndpointAddress(url));
var elements = binding.CreateBindingElements();
elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
var customBinding = new CustomBinding(binding);
customBinding.Elements.Clear();
customBinding.Elements.AddRange(elements.ToArray());
channel.Endpoint.Binding = customBinding;
channel.Credentials.UserName.UserName = username;
channel.Credentials.UserName.Password = password;
return channel;
}