SSL-сертификат WCF с использованием ЦС предприятия

Для приложения мне нужен SSL-сертификат для службы WCF,

Итак, мы установили его. Если я использую интернет-браузер с веб-браузером через https, у меня нет проблем, никаких предупреждений, ничего, поэтому я полагаю, что этот сертификат считается действительным для Windows.

Проблема в том, что когда я пытаюсь подключиться к своему серверу WCF, я получаю эту ошибку:

The X.509 certificate CN=myHostName, OU=tom, O=myDomainName,

L=MyLocation, S=SO, C=CH построение цепочки не удалось. Используемый сертификат имеет цепочку доверия, которую невозможно проверить. Замените сертификат или измените certificateValidationMode. Функция отзыва не смогла проверить отзыв, так как сервер отзыва был отключен.

Что может быть не так? Как я могу узнать, какая часть цепочки недействительна? Есть ли способ узнать, что является недостающей частью?

Вот мой код Сервер:

ServiceHost myHost = new ServiceHost(typeof(MyService));
WSHttpBinding binding = new WSHttpBinding
{
    ReaderQuotas = { MaxStringContentLength = int.MaxValue, MaxArrayLength = int.MaxValue, MaxDepth = int.MaxValue, MaxBytesPerRead = int.MaxValue, MaxNameTableCharCount = int.MaxValue },
    MaxReceivedMessageSize = int.MaxValue
};
TimeSpan timeoutSpan = TimeSpan.FromMilliseconds(timeout);
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;

binding.MaxBufferPoolSize = int.MaxValue;

//we set the security type
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

//we set the server's certificate
myHost.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, ConfigurationManager.AppSettings["Hostname"]);
myHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
//we add the endPoint(and we indicate which methods are exposed through the interface

myHost.AddServiceEndpoint(services[port], binding,                  String.Format("http://localhost:{0}", port));




//Some services doesn't need an authentication
if (!servicesWithoutAuth.Contains(services[port]))
{
    //We set the authentifier:
    myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
    myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();
    myHost.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;


    //we set the AuthorizationPolicy
    List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy> { new CustomAuthorizationPolicy() };
    myHost.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly();
}
else
{
    //We set the authentifier:
    myHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
    myHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new NoUserNamePasswordValidator();
}

//We bypass the certificate verification(our certificate is only self signed)
//HACK Only to desactivate the SSL check: 
ServicePointManager.ServerCertificateValidationCallback += ValidateCertificate;



//HACK: Remove when debug finished
private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslpolicyerrors)
{
    return true;
}

Моя клиентская сторона:

// the remote adress is of the form "net.tcp://localhost:8000"
string remoteAddress = String.Format("{0}://{1}:{2}", Tools.GetDescription(accessInfo.ServiceHost.Protocol), accessInfo.ServiceHost.HostName, accessInfo.PortNumber);

// HACK: binding depends on protocol -> switch over accessInfo.ServiceHost.Protocol

// avoid seralization/deserialization problems with large XML's
WSHttpBinding binding = new WSHttpBinding();
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
TimeSpan timeoutSpan = DateTime.Now.AddMinutes(30) - DateTime.Now;
binding.CloseTimeout = timeoutSpan;
binding.OpenTimeout = timeoutSpan;
binding.ReceiveTimeout = timeoutSpan;
binding.SendTimeout = timeoutSpan;
binding.ReliableSession.InactivityTimeout = timeoutSpan;


//++
binding.MaxBufferPoolSize = int.MaxValue;

//we set the security type
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

ChannelFactory<TService> channelFactory = new ChannelFactory<TService>(binding, remoteAddress);

channelFactory.Credentials.UserName.UserName = ((UsernamePasswordAuthentication)authInfos).Username;
channelFactory.Credentials.UserName.Password = ((UsernamePasswordAuthentication)authInfos).Password;


//We set the maxItemsInObjectGraph
foreach (OperationDescription op in channelFactory.Endpoint.Contract.Operations)
{
    DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
    if (dataContractBehavior != null)
    {
        dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
    }
}
SamlSecurityTokenAuthenticator authenticator = new SamlSecurityTokenAuthenticator(new List<SecurityTokenAuthenticator>(new SecurityTokenAuthenticator[] { new RsaSecurityTokenAuthenticator(), new X509SecurityTokenAuthenticator(X509CertificateValidator.None) }), TimeSpan.FromDays(5));

_service = channelFactory.CreateChannel();

person J4N    schedule 30.08.2011    source источник


Ответы (1)


Как я могу узнать, какая часть цепочки недействительна? Есть ли способ узнать, что является недостающей частью?

Что ж, по моему опыту, если вы откроете хранилище ключей и просмотрите его, вы должны увидеть, что ваш сертификат четко формирует цепочку. Я не знаю, какой инструмент вы используете для просмотра своего хранилища ключей (или используете ли вы хранилище ключей Windows), но когда вы просматриваете свой ключ, вы должны увидеть какую-то цепочку. Если цепочка сформирована правильно, она будет отображаться правильно и не будет иметь недостающих частей.

Я предполагаю, что когда вы импортировали свой ответ сертификата, он по какой-то причине не сформировал цепочку. Другими словами, ваш сертификат находится в вашем хранилище ключей как «не связанный» открытый ключ.

person djangofan    schedule 01.09.2011