Настройте клиент службы WCF с помощью аутентификации сертификата программно - PullRequest
10 голосов
/ 10 января 2012

Как мне настроить ServiceClient, используя программную аутентификацию сертификата в c #?
И я не хочу использовать .config.

       using(var srv = GetServiceInstance())
       {
            srv.DoStuff()
        }

        private  TheServiceClient GetServiceInstance()
        {
            var service = new TheServiceClient(CreateWsHttpBinding(), CreateEndpointAdress());
            return service;
        }
        private static WSHttpBinding CreateWsHttpBinding()
        {
        var wsHttpBinding = new WSHttpBinding();
        wsHttpBinding.Security.Mode = SecurityMode.Message;

        wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
        wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
        wsHttpBinding.Security.Transport.Realm = "";
        wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

        wsHttpBinding.Security.Message.NegotiateServiceCredential = true;
        wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

        wsHttpBinding.Name = "Bindingname";
        wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(1);
        wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(1);
        wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
        wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(1);
        wsHttpBinding.BypassProxyOnLocal = false;
        wsHttpBinding.TransactionFlow = false;
        wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
        wsHttpBinding.MaxBufferPoolSize = 524288;
        wsHttpBinding.MaxReceivedMessageSize = 65536;
        wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
        wsHttpBinding.TextEncoding = Encoding.UTF8;
        wsHttpBinding.UseDefaultWebProxy = true;
        wsHttpBinding.AllowCookies = false;

        wsHttpBinding.ReaderQuotas.MaxDepth = 32;
        wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384;
        wsHttpBinding.ReaderQuotas.MaxStringContentLength = 8192;
        wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096;
        wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;

        wsHttpBinding.ReliableSession.Ordered = true;
        wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
        wsHttpBinding.ReliableSession.Enabled = false;

        return wsHttpBinding;
    }
        private static EndpointAddress CreateEndpointAdress()
        {
            var store = new X509Store(StoreName.TrustedPeople, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            var cert = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=Certname", false)[0];
            store.Close();

        var endpointIdentity = EndpointIdentity.CreateX509CertificateIdentity(cert);
        var endpoint = new EndpointAddress(new Uri("ServiceUri"), endpointIdentity);

        return endpoint;
    }

Так вот, что у меня так далеко!Использование этого возвращает ошибку:

Сертификат клиента не предоставлен.Укажите сертификат клиента в ClientCredentials.

У кого-нибудь есть идея?Будьте нежны, я новичок в этом!

Ответы [ 3 ]

9 голосов
/ 10 января 2012

Как было обнаружено в комментариях к другому ответу, вам нужно установить service.ClientCredentials.ClientCertificate.Certificate напрямую.

0 голосов
/ 19 января 2012

Я думаю, вам не хватает описания контракта. Вот небольшой пример того, как это сделать. Если у вас есть дальнейшие проблемы, у меня есть полный рабочий код. Я помогу тебе.

ContractDescription Contract = ContractDescription.GetContract (typeof (IEvalService), typeof (EvalServiceClient));

Вы должны инициализироваться с клиентом перед открытием прокси. Надеюсь, это сработает.

веселись

0 голосов
/ 10 января 2012

может потребоваться проверить, виден ли этот сертификат для учетной записи компьютера. Предполагается, что вы отлажены до следующей точки:

var cert = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=Certname", false)[0];

и он говорит, что не можетнайти это?

...