Błąd przy wywołaniu metody usługi sieciowej

0

Witajcie.
Piszę klienta, który łączy się z SAP BC i wykonuje udostępnioną metodę.
Do połączenia wymagane jest podanie username, password. Transmisja jest po HTTP zabezpieczona certyfikatem SSL.
Kod poniżej działa poprawnie tzn zestawiane jest połączenie.

            var binding = new BasicHttpBinding();
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
            binding.Security.Mode = BasicHttpSecurityMode.Transport;

            var address = new EndpointAddress("https://xxx.xxx.xxx.xxx:1000/soap");

            ServiceReference1.httpsoapPortTypeClient client = new ServiceReference1.httpsoapPortTypeClient(binding, address);

            client.ClientCredentials.UserName.UserName = "xxx";
            client.ClientCredentials.UserName.Password = "yyy";
            Console.WriteLine("Nawiązuję połączenie");
            client.Open();
            Console.WriteLine("Jestem w środku");
            client.Close();
            Console.WriteLine("Kończę połączenie");

Problem pojawia się kiedy po połączeniu chcę wywołać wspomnianą metodę (przekazuje do niej jeden parametr i odbieram odpowiedź).

client.Open();
Console.WriteLine("Jestem w środku");
var info = client.receive(dane); //<----- tu wywala się program
client.Close();
Console.WriteLine("Kończę połączenie");

Otrzymuje taki oto radosny komunikat błędu.

System.ServiceModel.Security.SecurityNegotiationException was unhandled
  HResult=-2146233087
  Message=Nie można ustanowić relacji zaufania dla bezpiecznego kanału SSL/TLS z urzędem „xxx.xxx.xxx.xxx:1000”.
  Source=mscorlib
  StackTrace:
    Server stack trace: 
       w System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
       w System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       w System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
       w System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
       w System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       w System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       w System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    Exception rethrown at [0]: 
       w System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       w System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       w ConsoleApplication2.ServiceReference1.httpsoapPortType.receive(receiveRequest request)
       w ConsoleApplication2.ServiceReference1.httpsoapPortTypeClient.ConsoleApplication2.ServiceReference1.httpsoapPortType.receive(receiveRequest request) w ConsoleApplication2\Service References\ServiceReference1\Reference.cs:wiersz 211
       w ConsoleApplication2.ServiceReference1.httpsoapPortTypeClient.receive(requestData requestData) w ConsoleApplication2\ConsoleApplication2\Service References\ServiceReference1\Reference.cs:wiersz 217
       w ConsoleApplication2.Program.Main(String[] args) w ConsoleApplication2\ConsoleApplication2\Program.cs:wiersz 154
       w System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       w System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       w System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       w System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Net.WebException
       HResult=-2146233079
       Message=Połączenie podstawowe zostało zakończone: Nie można ustanowić relacji zaufania dla bezpiecznego kanału SSL/TLS.
       Source=System
       StackTrace:
            w System.Net.HttpWebRequest.GetResponse()
            w System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
       InnerException: System.Security.Authentication.AuthenticationException
            HResult=-2146233087
            Message=Według procedury walidacji certyfikat zdalny jest nieprawidłowy.
            Source=System
            StackTrace:
                 w System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
                 w System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
                 w System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
                 w System.Net.TlsStream.CallProcessAuthentication(Object state)
                 w System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
                 w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
                 w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
                 w System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
                 w System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
                 w System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
                 w System.Net.ConnectStream.WriteHeaders(Boolean async)
            InnerException: 

Więc co jest nie tak ?
Gdzie znaleźć info o rozwiązaniu problemu ?

Pozdrawiam i dziękuję za pomoc.

1

Ok, temat do zamknięcia.
Problemem był certyfikat SSL pobierany z punktu końcowego a właściwie jego walidacja której nie przechodził.
Znalazłem w necie rozwiązanie polegające na wymuszeniu poprawnej walidacji każdego ceryfikatu SSL pobieranego z punktu końcowego.
Ważne żeby tą walidację zrobić przed połączeniem.
Gdzieś na początku kodu przed połączeniem wywołałem metodę z utworzonej klasy Util i tyle.

Util.SetCertificatePolicy();

A tak wygląda klasa Util.

public static class Util
    {
        public static void SetCertificatePolicy()
        {
            ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
        }
        private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
            // trust any certificate!!!
            //System.Console.WriteLine("Warning, trust any certificate");
            return true;
        }
    }

Pozdrawiam.

0
wilkolaski napisał(a):

Ok, temat do zamknięcia.
Problemem był certyfikat SSL pobierany z punktu końcowego a właściwie jego walidacja której nie przechodził.
Znalazłem w necie rozwiązanie polegające na wymuszeniu poprawnej walidacji każdego ceryfikatu SSL pobieranego z punktu końcowego.
Ważne żeby tą walidację zrobić przed połączeniem.
Gdzieś na początku kodu przed połączeniem wywołałem metodę z utworzonej klasy Util i tyle.

Util.SetCertificatePolicy();

A tak wygląda klasa Util.

public static class Util
    {
        public static void SetCertificatePolicy()
        {
            ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
        }
        private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
            // trust any certificate!!!
            //System.Console.WriteLine("Warning, trust any certificate");
            return true;
        }
    }

Pozdrawiam.

Można zwięźlej:
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

2

Jeżeli robisz to na produkcji, to przestań i napraw certyfikat, a nie wyłączaj mechanizmy bezpieczeństwa.

0

jak naprawić certyfikat ??

1 użytkowników online, w tym zalogowanych: 0, gości: 1