为什么在异步操作

时间:2017-02-21 12:30:31

标签: wcf wcf-security

使用X509证书为Authencation启用安全功能时,未建立与服务器的连接。当客户端进行异步操作调用时,我发现此问题。以下代码适用于同步操作。例如,如果调用是使用TrainHealth而不是BeginTrainHealth,则代码可以正常工作。据我了解,安全性与操作是同步还是异步无关。 任何有关为什么这不起作用的帮助表示赞赏。

合同:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://www.bane.dk/services/fbane/2014/02/20", ConfigurationName = "Alstom.SmartBus.ESBBridge.ExternalIOPlugins.TrainData.TrainDataPort")]
public interface IStudentService
{
    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, AsyncPattern = false, Action = "TrainHealth")]
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    void TrainHealth(int test);

    [System.ServiceModel.OperationContractAttribute(IsOneWay = true, AsyncPattern = true, Action = "TrainHealth")]
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    System.IAsyncResult BeginTrainHealth(int test, System.AsyncCallback callback, object asyncState);

    void EndTrainHealth(System.IAsyncResult result);
}

服务器代码:

class Program
    {
        static void Main(string[] args)
        {
            ServiceHost studentServiceHost = null;
            try
            {
                //Base Address for StudentService
                Uri httpBaseAddress = new Uri("https://10.107.64.33:5060/StudentService");

                //Instantiate ServiceHost
                studentServiceHost = new ServiceHost(typeof(StudentService), httpBaseAddress);

                CustomBinding binding = CreateBinding();
                ServiceEndpoint endpoint_GD = studentServiceHost.AddServiceEndpoint(typeof(IStudentService), binding, httpBaseAddress);

                //Add Endpoint to Host
                studentServiceHost.AddServiceEndpoint(typeof(IStudentService), binding, httpBaseAddress + "mex");

                //Metadata Exchange
                ServiceMetadataBehavior serviceBehavior = new ServiceMetadataBehavior();
                serviceBehavior.HttpsGetEnabled = true;
                studentServiceHost.Description.Behaviors.Add(serviceBehavior);
                var behavior = studentServiceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
                behavior.IncludeExceptionDetailInFaults = true;
                studentServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;
                studentServiceHost.Credentials.ClientCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine;

                studentServiceHost.Credentials.ServiceCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "10.107.64.33");

                ServiceSecurityAuditBehavior newAudit = new ServiceSecurityAuditBehavior();
                newAudit.AuditLogLocation = AuditLogLocation.Application;
                newAudit.MessageAuthenticationAuditLevel = AuditLevel.SuccessOrFailure;
                newAudit.ServiceAuthorizationAuditLevel = AuditLevel.SuccessOrFailure;
                newAudit.SuppressAuditFailure = false;
                studentServiceHost.Description.Behaviors.Remove<ServiceSecurityAuditBehavior>();
                studentServiceHost.Description.Behaviors.Add(newAudit);

                studentServiceHost.Open();

                Console.WriteLine("Service is live now at : {0}", httpBaseAddress);
                Console.ReadKey();

            }
            catch (Exception ex)
            {
                studentServiceHost = null;
                Console.WriteLine("There is an issue with StudentService" + ex.Message);
                Console.ReadKey();

            }
        }

        public static CustomBinding CreateBinding()
        {
            CustomBinding binding = new CustomBinding();
            binding.Elements.Add(new ReliableSessionBindingElement());
            TransportSecurityBindingElement sec = new TransportSecurityBindingElement();
            binding.Elements.Add(sec);
            binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8));
            binding.Elements.Add(new HttpsTransportBindingElement()
            {
                RequireClientCertificate = true
            });

            return binding;
        }
    }

客户代码:

 class Program
    {
        static ChannelFactory<IStudentService> runTrainSvcCF = null;

        static IStudentService runTrainSvcProxy;
        static void Main(string[] args)
        {
            StartClient();
        }

        private static void StartClient()
        {
            EndpointAddress endPoint = new EndpointAddress(new Uri("https://10.107.64.33:5060/StudentService"), EndpointIdentity.CreateDnsIdentity("10.107.64.34"));

            CustomBinding binding = CreateBinding();
            runTrainSvcCF = new ChannelFactory<IStudentService>(binding, endPoint);
            System.ServiceModel.Description.ClientCredentials credentials = runTrainSvcCF.Credentials;
            credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
                                                         System.Security.Cryptography.X509Certificates.StoreName.My,
                                                         System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
                                                         "10.107.64.34");
            ServicePointManager.MaxServicePointIdleTime = 0;
            credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;
            ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(ValidateRemoteCertificate);
            runTrainSvcProxy = runTrainSvcCF.CreateChannel();
            try
            {
                runTrainSvcProxy.BeginTrainHealth(88, null, null);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        private static bool ValidateRemoteCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert,
                                              System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors policyErrors)
        {
            return true;
        }



        public static CustomBinding CreateBinding()
        {
            CustomBinding binding = new CustomBinding();
            binding.Elements.Add(new ReliableSessionBindingElement());
            binding.Elements.Add(new TransportSecurityBindingElement());
            binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, Encoding.UTF8));
            binding.Elements.Add(new HttpsTransportBindingElement()
            {
                RequireClientCertificate = true
            });

            return binding;
        }
    }

0 个答案:

没有答案