WCF wsdualhttpBinding пользовательское имя
Я получил очень досадную ошибку: Мой сценарий - простой сервер сообщений / почты, реализованный в WCF с помощью wsdualhttpbinding (двойной для обратных вызовов, онлайн-обновление нового сообщения).
Все настройки безопасности записаны в коде (нет *.config вообще). При первом соединении клиент выбрасывает следующее [System.Security.Cryptography.CryptographicException] = {"Bad Length.\ R \n"} с внутренним исключением NULL, поэтому углубление в глубину невозможно. Конфигурация сервера:
WSDualHttpBinding binding = new WSDualHttpBinding(WSDualHttpSecurityMode.Message);
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
Uri baseServiceAddress = new Uri(@"http://"+Environment.MachineName+":7921/Mail/");
host = new ServiceHost(theMightyMailServer,baseServiceAddress);
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = validator;
host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.Root, X509FindType.FindByIssuerName, "MailServer");
ServiceDebugBehavior d = new ServiceDebugBehavior();
d.IncludeExceptionDetailInFaults = true;
host.Description.Behaviors.Remove<ServiceDebugBehavior>();
host.Description.Behaviors.Add(d);
ServiceMetadataBehavior b = new ServiceMetadataBehavior();
b.HttpGetEnabled = true;
host.Description.Behaviors.Remove<ServiceMetadataBehavior>();
host.Description.Behaviors.Add(b);
var mexBinding = MetadataExchangeBindings.CreateMexHttpBinding();
host.AddServiceEndpoint(typeof(IMailServer), binding, "Service");
host.AddServiceEndpoint(typeof(IMetadataExchange),mexBinding,"");
host.Open();
Конфигурация клиента:
client = new MailServerReference.MailServerClient(new InstanceContext(this));
client.ClientCredentials.UserName.UserName = currentUser.UserName;
client.ClientCredentials.UserName.Password = currentUser.Password;
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.Root,X509FindType.FindByIssuerName, "MailServer");
currentUser.ID = client.getUID();
client.RegisterOnServer(currentUser.ID);
return true;
}
catch (Exception ex) { MessageBox.Show(ex.Message); return false; }
Буду очень признателен за любую помощь. И, кстати, я новичок в WCF, поэтому, возможно, мне не хватает какой-то базовой концепции.
1 ответ
Я бы попробовал установить ServiceCertificate
а также ClientCertificate
к тому же и на клиенте и на сервере. По крайней мере, так я это сделал. Это было какое-то время, но я думаю, что у меня были проблемы, когда был установлен только один сертификат или другой, а не оба.
Изменить для дополнительной информации:
В моем случае я использую CustomBinding
вместо WSDualHttpBinding
но в итоге я использовал один и тот же сертификат для ServiceCertificate и ClientCertificate с обеих сторон (клиент и сервер).
Точнее, у меня есть класс, который расширяет System.ServiceModel.Description.ServiceCredentials
public class MyServiceCredentials : ServiceCredentials
{
public MyServiceCredentials() : base()
{
LoadCertificate();
}
public MyServiceCredentials(MyServiceCredentials other) : base(other)
{
LoadCertificate();
}
private void LoadCertificate()
{
ServiceCertificate.Certificate = _cert;
ClientCertificate.Certificate = _cert;
ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
}
}
И я передаю один из них моему конструктору CustomBinding в реализации клиента и сервера.
Во всяком случае, я думаю, потому что Message
защита включена для привязки, она ожидает, что будет защита на уровне сообщений в обоих направлениях, поэтому ей нужен сертификат с обеих сторон (ServiceCertificate и ClientCertificate).
Я могу быть совершенно неправ, хотя, я просто говорю; попробуйте и посмотрите, поможет ли это...