Исключение безопасности WCF с Windows XP Embedded - PullRequest
0 голосов
/ 03 июня 2011

У меня есть веб-служба, размещенная в службе Windows, которая использует BasicHttpBinding с защитой транспорта через самозаверяющий сертификат. Служба работает нормально, за исключением случаев, когда она находится на Windows XP Embedded Standard. С отключенной защитой он работает, но не когда он включен. Я могу обновить ссылку на службу из Visual Studio 2008, но когда я пытаюсь выполнить какие-либо вызовы методов службы, происходит сбой со следующим исключением:

Не удалось найти процессор безопасности заголовок безопасности в сообщении. это может быть потому, что сообщение является необеспеченная ошибка или потому, что есть несоответствие между общающиеся стороны. Это может происходят, если служба настроена для безопасность и клиент не использует безопасность.

Я проверил, что звонки даже не делают, поскольку код проверки учетных данных пользователя. На самом деле, трассировка WCF на стороне сервиса ничего не показывает. Это наводит меня на мысль, что это проблема WCF в XP Embedded, но я пробовал .NET 3.0, .NET 3.0 SP1 и .NET 4.0, и ни один из них не решил эту проблему. Еще один интересный трюк, который заставляет меня думать, что это WCF: когда я запускаю службу на своем ноутбуке для разработки и пробую клиент из встроенной системы XP, я получаю ту же ошибку.

Вот полное исключение на стороне клиента и трассировка стека:

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 #, используемый для настройки службы, если это поможет. Заранее спасибо.

...