2015-07-28 4 views
1

Я совершенно новый для 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 

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

Спасибо всем!

ответ

0

Ok,

после прохождения через множество обучающих и демонстрационных приложений, я понял, что лучший способ, чтобы идти вперед на самом деле использует хранилище сертификатов на Windows. Тем не менее, я все же могу рассмотреть гибридное решение, в котором у Сервера есть сертификаты в хранилище сертификатов, и клиент имеет встроенный в ресурс. Если вы боретесь с WCF и сертификаты, взглянуть на эти ссылки:

IIS7 Permissions Overview - ApplicationPoolIdentity

Я был в состоянии создать транспорта, а также сообщений обеспеченных веб-службы WCF. Я бы предложил ПРОЧИТАТЬ связанные статьи, потому что есть так много информации, которая заставит вас понять сертификаты и их использование.Особенно, когда вы имеете дело с собственными сертификатами!

Я закончил реализацию wsHttpBinding, используя режим безопасности сообщений + сертификат клиента с ChainTrust.

Надеюсь, это поможет кому-то еще!

Смежные вопросы