Windows XP Embedded的WCF安全性异常

时间:2011-06-03 03:00:19

标签: .net wcf windows-xp-embedded

我有一个安装在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#代码,如果这将有所帮助。提前谢谢。

0 个答案:

没有答案