Я совершенно новый для WCF и пытаюсь окунуться в безопасность. Я все еще читаю и изучаю, но дошел до того, что получил рабочую версию WCF с аутентификацией сертификата. Я знаю, что код имеет некоторые недостатки; однако моя первоначальная цель заключалась в создании связи с использованием аутентификации сертификатов. Кроме того, я хотел создать все программно (без конфигураций Web.config для служб или клиентов). Причина этого заключается в том, что клиент должен иметь возможность связать сборку (Class Library) и получить доступ к серверу. Кроме того, я загружаю сертификаты из файловой системы (опять же, я знаю, что это не безопасно). Я хотел бы получить немного обратной связи.Программно реализовать WCF с сертификатом
Следующий фрагмент клиента создает объект, который я могу использовать для подключения к серверу. Анонимный тип T - мой сервисный интерфейс, например. IService.
Вот моя реализация клиента:
var url = "URL TO WS";
var binding = new WSHttpBinding
{
Security =
{
Mode = SecurityMode.Message,
Message = {ClientCredentialType = MessageCredentialType.Certificate}
}
};
var endpoint = new EndpointAddress(url);
var channelFactory = new ChannelFactory<T>(binding, endpoint);
if (channelFactory.Credentials != null)
{
channelFactory.Credentials.ClientCertificate.Certificate =
new X509Certificate2(@"PATH\TO\Client.pfx"); // Client Certificate PRIVATE & PUBLIC Key
channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; // I know this is not good, but I dont have a valid certificate from a trusted entity
}
wcfClient = channelFactory.CreateChannel();
return wcfClient;
Служба является немного более сложным. Я использую файлы .svc с их кодом. Если я правильно понимаю использование файлов .svc, то я считаю, что это точка входа, где платформа .NET создает ServiceHost и автоматически открывает ее? В моей реализации я не открываю ServiceHost, я только реализовал ServiceHostFactoryBase и ссылался на него на языке разметки .svc. Посмотрите раздел Factory - это та часть, в которой я реализую свой собственный хост-сервер.
<%@ ServiceHost Language="C#" Debug="true"
Service="Service.Services.LevelService" CodeBehind="LevelService.svc.cs"
Factory="Service.Security.ServiceHostFactory.HostFactory" %>
И мой пользовательский хост завод выглядит следующим образом:
public class HostFactory : ServiceHostFactoryBase
{
public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
var serviceType = Type.GetType(constructorString);
if (serviceType.GetInterfaces().Count() != 1)
throw new NotImplementedException("The service can only have one implemented interface");
var interfaceType = serviceType.GetInterfaces()[0];
var myServiceHost = new ServiceHost(serviceType, baseAddresses);
var httpBinding = new WSHttpBinding();
httpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
httpBinding.Security.Mode = SecurityMode.Message;
myServiceHost.Credentials.ServiceCertificate.Certificate = new X509Certificate2(@"PATH\TO\Server.pfx");
myServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
myServiceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new MyX509CertificateValidator();
myServiceHost.Credentials.ClientCertificate.Certificate = new X509Certificate2(@"PATH\TO\Client.cer");
myServiceHost.AddServiceEndpoint(interfaceType, httpBinding, String.Empty);
return myServiceHost;
}
}
Обычай валидатор doess't делать еще, но здесь это так:
public class MyX509CertificateValidator : X509CertificateValidator
{
public override void Validate(X509Certificate2 certificate)
{
// Check that there is a certificate.
if (certificate == null)
{
throw new ArgumentNullException("certificate");
}
// Check that the certificate issuer matches the configured issuer.
//throw new SecurityTokenValidationException("Certificate was not issued by a trusted issuer");
}
}
Если я понимаю, правильно, сервер имеет ТОЛЬКО PUBLIC-ключ клиента, зарегистрированный, поскольку я только ссылаюсь на файл .cer.
Мой большой вопрос теперь, если бы я хотел получить что-то подобное на производственном сервере - и позволяет предположить, что на самом деле никто не получит исполняемые файлы (включая сертификаты), будет ли это возможным решением для предотвращения нежелательных людей моего веб-сервиса? В принципе, я не хочу, чтобы кто-то еще использовал мой веб-сервис - только если у вас есть соответствующий сертификат. Кроме того, как большая часть проблемы является та часть, где я поставил на клиенте:
CertificateValidationMode = X509CertificateValidationMode.None
Я знаю, что есть много вопросов, - но в целом, я хотел бы знать, если я сделал некоторые фундаментальные ошибки в этой реализации.
Спасибо всем!