SSL-сертификат WCF с использованием корпоративного CA - PullRequest
1 голос
/ 30 августа 2011

Для приложения мне нужен сертификат 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();

1 Ответ

0 голосов
/ 01 сентября 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...