我有一个安装在Windows服务中的Web服务,它通过自签名证书使用BasicHttpBinding和传输安全性。该服务工作正常,除非它驻留在Windows XP Embedded Standard上。安全关闭后,它可以正常工作,但不会在它开启时使用。我可以从Visual Studio 2008中更新服务引用,但是当我尝试对服务方法进行任何调用时,它会失败并出现以下异常:
安全处理器无法找到 消息中的安全标头。这个 可能是因为消息是一个 无担保的错误或因为有一个 结合不匹配 沟通各方。这个可以 如果配置了服务,则会发生 安全性和客户端没有使用 安全
我已经验证了这些电话甚至没有达到用户凭据验证码。实际上,服务端的WCF跟踪根本没有显示任何内容。这让我相信这是XP Embedded上的WCF问题,但我尝试过.NET 3.0,.NET 3.0 SP1和.NET 4.0,但这些都没有解决问题。另一个有趣的消息让我觉得它是WCF:当我在我的开发笔记本电脑上运行服务并从XP Embedded系统尝试客户端时,我得到了同样的错误。
这里是完整的客户端异常和堆栈跟踪:
System.ServiceModel.Security.MessageSecurityException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Security processor was unable to find a security header in the message. This might be because the message is an unsecured fault or because there is a binding mismatch between the communicating parties. This can occur if the service is configured for security and the client is not using security.
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessageCore(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
... [I removed the higher level calls for brevity sake.]
以下是客户端app.config的适用部分:
<basicHttpBinding>
<binding name="BasicHttpBinding_IData" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
<client>
<endpoint address="https://191.16.115.102:8000/data/Service/dataService"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IData"
contract="Data.IData" name="BasicHttpBinding_IData" />
</client>
这是客户端代码,设置为绕过自签名证书的身份验证:
class Program {
private static bool AlwaysValid(object sender, X509Certificate cert,
X509Chain chain, SslPolicyErrors errors) {
return true;
}
static void Main(string[] args) {
ServicePointManager.ServerCertificateValidationCallback += AlwaysValid;
try {
var client = new Data.DataClient();
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
client.Open();
int state = client.GetSystemState();
Console.WriteLine("Current state is: {0}", state);
}
catch (Exception ex) {
Console.WriteLine("Error: {0}", ex.Message);
}
finally {
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
}
}
对此的任何见解将不胜感激。我可以提供用于设置服务的C#代码,如果这将有所帮助。提前谢谢。