Поделиться через


Сертификат безопасности сообщений

В примере MessageSecurity показано, как реализовать приложение, которое использует WS-Security с проверкой подлинности сертификата X.509 версии 3 для клиента и требует проверки подлинности сервера с помощью сертификата X.509 v3 сервера. В этом примере используются параметры по умолчанию, чтобы все сообщения приложения между клиентом и сервером были подписаны и зашифрованы. Этот пример основан на WSHttpBinding и состоит из клиентской консольной программы и библиотеки, размещенной в Internet Information Services (IIS). Служба реализует контракт, определяющий шаблон связи с запросом и ответом.

Заметка

Процедура установки и инструкции по сборке для этого примера находятся в конце этого раздела.

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

public class CalculatorService : ICalculator
{
    public string GetCallerIdentity()
    {
        // The client certificate is not mapped to a Windows identity by default.
        // ServiceSecurityContext.PrimaryIdentity is populated based on the information
        // in the certificate that the client used to authenticate itself to the service.
        return ServiceSecurityContext.Current.PrimaryIdentity.Name;
    }
    ...
}

Служба предоставляет одну конечную точку для взаимодействия со службой и одной конечной точкой для предоставления документа WSDL службы с помощью протокола WS-MetadataExchange, определенного с помощью файла конфигурации (Web.config). Конечная точка состоит из адреса, привязки и контракта. Привязка настраивается с помощью стандартного элемента <wsHttpBinding>, который по умолчанию использует безопасность сообщений. Этот пример задает атрибут clientCredentialType сертификату, чтобы требовать проверку подлинности клиента.

<system.serviceModel>
    <protocolMapping>
      <add scheme="http" binding="wsHttpBinding"/>
    </protocolMapping>
    <bindings>
      <wsHttpBinding>
        <!--
        This configuration defines the security mode as Message and
        the clientCredentialType as Certificate.
        -->
        <binding>
          <security mode ="Message">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
        The serviceCredentials behavior allows one to define a service certificate.
        A service certificate is used by the service to authenticate itself to its clients and to provide message protection.
        This configuration references the "localhost" certificate installed during the setup instructions.
        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            <clientCertificate>
              <!--
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
            is in the user's Trusted People store, then it will be trusted without performing a
            validation of the certificate's issuer chain. This setting is used here for convenience so that the
            sample can be run without having to have certificates issued by a certification authority (CA).
            This setting is less secure than the default, ChainTrust. The security implications of this
            setting should be carefully considered before using PeerOrChainTrust in production code.
            -->
              <authentication certificateValidationMode="PeerOrChainTrust" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Поведение указывает учетные данные службы, которые используются для аутентификации клиента при обращении к службе. Имя субъекта сертификата сервера указывается в атрибуте findValue в элементе <serviceCredentials>.

<!--For debugging purposes, set the includeExceptionDetailInFaults attribute to true.-->
<behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
        The serviceCredentials behavior allows one to define a service certificate.
        A service certificate is used by the service to authenticate itself to its clients and to provide message protection.
        This configuration references the "localhost" certificate installed during the setup instructions.
        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            <clientCertificate>
              <!--
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
            is in the user's Trusted People store, then it will be trusted without performing a
            validation of the certificate's issuer chain. This setting is used here for convenience so that the
            sample can be run without having to have certificates issued by a certification authority (CA).
            This setting is less secure than the default, ChainTrust. The security implications of this
            setting should be carefully considered before using PeerOrChainTrust in production code.
            -->
              <authentication certificateValidationMode="PeerOrChainTrust" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>

Конфигурация конечной точки клиента состоит из абсолютного адреса конечной точки службы, привязки и контракта. Привязка клиента настроена с соответствующим режимом безопасности и режимом проверки подлинности. При выполнении в сценарии между компьютерами убедитесь, что адрес конечной точки службы изменён соответствующим образом.

<system.serviceModel>
    <client>
      <!-- Use a behavior to configure the client certificate to present to the service. -->
      <endpoint address="http://localhost/servicemodelsamples/service.svc" binding="wsHttpBinding" bindingConfiguration="Binding1" behaviorConfiguration="ClientCertificateBehavior" contract="Microsoft.Samples.Certificate.ICalculator"/>
    </client>

    <bindings>
      <wsHttpBinding>
        <!--
        This configuration defines the security mode as Message and
        the clientCredentialType as Certificate.
        -->
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
...
</system.serviceModel>

Реализация клиента может задать используемый сертификат с помощью файла конфигурации или кода. В следующем примере показано, как задать сертификат для использования в файле конфигурации.

<system.serviceModel>
  ...

<behaviors>
      <endpointBehaviors>
        <behavior name="ClientCertificateBehavior">
          <!--
        The clientCredentials behavior allows one to define a certificate to present to a service.
        A certificate is used by a client to authenticate itself to the service and provide message integrity.
        This configuration references the "client.com" certificate installed during the setup instructions.
        -->
          <clientCredentials>
            <clientCertificate findValue="client.com" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
            <serviceCertificate>
              <!--
            Setting the certificateValidationMode to PeerOrChainTrust means that if the certificate
            is in the user's Trusted People store, then it will be trusted without performing a
            validation of the certificate's issuer chain. This setting is used here for convenience so that the
            sample can be run without having to have certificates issued by a certificate authority (CA).
            This setting is less secure than the default, ChainTrust. The security implications of this
            setting should be carefully considered before using PeerOrChainTrust in production code.
            -->
              <authentication certificateValidationMode="PeerOrChainTrust"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

</system.serviceModel>

В следующем примере показано, как вызвать службу в программе.

// Create a client.
CalculatorClient client = new CalculatorClient();

// Call the GetCallerIdentity service operation.
Console.WriteLine(client.GetCallerIdentity());
...
//Closing the client gracefully closes the connection and cleans up resources.
client.Close();

При запуске примера запросы и ответы операции отображаются в окне консоли клиента. Нажмите клавишу ВВОД в окне клиента, чтобы завершить работу клиента.

CN=client.com
Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.

Пакетный файл Setup.bat, включенный в примеры безопасности сообщений, позволяет настроить клиент и сервер с соответствующими сертификатами для запуска размещенного приложения, требующего безопасности на основе сертификатов. Пакетный файл можно запускать в трех режимах. Введите setup.bat в командной строке разработчика Visual Studio для работы в режиме одного компьютера; для режима службы введите setup.bat service; а для клиентского режима введите setup.bat client. Используйте режим клиента и сервера при запуске примера на компьютерах. Дополнительные сведения см. в процедуре установки в конце этого раздела. Ниже приведен краткий обзор различных разделов пакетных файлов, чтобы их можно было изменить для выполнения в соответствующей конфигурации:

  • Создание сертификата клиента.

    Следующая строка в пакетном файле создает сертификат клиента. Указанное имя клиента используется в имени субъекта созданного сертификата. Сертификат хранится в хранилище My в расположении хранилища CurrentUser.

    echo ************
    echo making client cert
    echo ************
    makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%CLIENT_NAME% -sky exchange -pe
    
  • Установка сертификата клиента в доверенное хранилище сертификатов сервера.

    Следующая строка в пакетном файле копирует сертификат клиента в хранилище TrustedPeople сервера, чтобы сервер смог принять соответствующие решения доверия или без доверия. Чтобы сертификат, установленный в хранилище TrustedPeople, был доверен службой Windows Communication Foundation (WCF), необходимо задать режим проверки сертификата клиента PeerOrChainTrust или PeerTrust. См. предыдущий пример конфигурации службы, чтобы узнать, как это можно сделать с помощью файла конфигурации.

    echo ************
    echo copying client cert to server's LocalMachine store
    echo ************
    certmgr.exe -add -r CurrentUser -s My -c -n %CLIENT_NAME% -r LocalMachine -s TrustedPeople
    
  • Создание сертификата сервера.

    Следующие строки из пакетного файла Setup.bat создают используемый сертификат сервера.

    echo ************
    echo Server cert setup starting
    echo %SERVER_NAME%
    echo ************
    echo making server cert
    echo ************
    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe
    

    Переменная %SERVER_NAME% указывает имя сервера. Сертификат хранится в хранилище LocalMachine. Если пакетный файл Setup.bat запускается с аргументом, таким как служба (например, setup.bat служба), то %SERVER_NAME% содержит полностью определенное доменное имя компьютера. В противном случае по умолчанию используется localhost.

  • Установка сертификата сервера в доверенное хранилище сертификатов клиента.

    В следующей строке сертификат сервера копируется в хранилище доверенных пользователей клиента. Этот шаг необходим, так как сертификаты, созданные Makecert.exe, не являются неявно доверенными клиентской системой. Если у вас уже есть сертификат, основанный на доверенном корневом сертификате клиента, например, выданном Microsoft, то этот шаг по добавлению серверного сертификата в хранилище сертификатов клиента не требуется.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    
  • Предоставление разрешений на закрытый ключ сертификата.

    Следующие строки в файле Setup.bat делают сертификат сервера, хранящийся в хранилище LocalMachine, доступным для учетной записи рабочего процесса ASP.NET.

    echo ************
    echo setting privileges on server certificates
    echo ************
    for /F "delims=" %%i in ('"%ProgramFiles%\ServiceModelSampleTools\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i
    set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
    (ver | findstr /C:"5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
    echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R
    iisreset
    

    Заметка

    Если вы используете неамериканскую английскую версию Windows, то необходимо отредактировать файл Setup.bat и заменить имя учетной записи "NT AUTHORITY\NETWORK SERVICE" эквивалентом для вашего региона.

Заметка

Средства, используемые в этом пакетном файле, находятся в папке C:\Program Files\Microsoft Visual Studio 8\Common7\tools или C:\Program Files\Microsoft SDKs\Windows\v6.0\bin. Один из этих каталогов должен находиться в системном пути. Если у вас установлен Visual Studio, самый простой способ добавить этот каталог в путь — открыть командную строку разработчика для Visual Studio. Щелкните Запустить, а затем выберите Все программы, Visual Studio 2012, Сервис. В этой командной строке уже настроены соответствующие пути. В противном случае необходимо добавить соответствующий каталог в путь вручную.

Настройка, сборка и запуск примера

  1. Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.

  2. Чтобы создать версию решения на C# или Visual Basic .NET, следуйте инструкциям по сборке примеров Windows Communication Foundation .

Запуск примера на том же компьютере

  1. Откройте командную строку разработчика для Visual Studio с правами администратора и запустите Setup.bat из образца папки установки. При этом устанавливаются все сертификаты, необходимые для выполнения примера.

    Заметка

    Пакетный файл Setup.bat предназначен для запуска из командной строки разработчика для Visual Studio. Для этого необходимо, чтобы переменная среды пути указывала на каталог, в котором установлен пакет SDK. Эта переменная среды автоматически устанавливается в командной строке разработчика для Visual Studio (2010).

  2. Проверьте доступ к службе с помощью браузера, введя адрес http://localhost/servicemodelsamples/service.svc.

  3. Запустите Client.exe из \client\bin. Действие клиента отображается в клиентском консольном приложении.

  4. Если клиент и служба не могут взаимодействовать, см. рекомендации по устранению неисправностей для примеров WCF.

Для запуска примера на нескольких компьютерах

  1. Создайте каталог на компьютере службы. Создайте виртуальное приложение с именем servicemodelsamples для этого каталога с помощью средства управления службами IIS.

  2. Скопируйте файлы программы службы из \inetpub\wwwroot\servicemodelsamples в виртуальный каталог на компьютере службы. Убедитесь, что файлы копируются в подкаталоге \bin. Кроме того, скопируйте Setup.bat, Cleanup.batи ImportClientCert.bat файлы на компьютер службы.

  3. Создайте каталог на клиентском компьютере для двоичных файлов клиента.

  4. Скопируйте файлы клиентской программы в каталог клиента на клиентском компьютере. Кроме того, скопируйте Setup.bat, Cleanup.batи ImportServiceCert.bat файлы в клиент.

  5. На сервере запустите службу setup.bat в командной строке разработчика для Visual Studio с правами администратора. При запуске setup.bat с аргументом службы создается сертификат службы с полным доменным именем компьютера, который затем экспортируется в файл с именем Service.cer.

  6. Измените Web.config, чтобы отразить новое имя сертификата (в атрибуте findValue в <serviceCertificate>), которое совпадает с полным доменным именем компьютера.

  7. Скопируйте файл Service.cer из каталога службы в клиентский каталог на клиентском компьютере.

  8. На клиенте запустите setup.bat клиента в командной строке разработчика для Visual Studio с правами администратора. При выполнении setup.bat с аргументом клиента создается сертификат клиента с именем client.com и экспортируется сертификат клиента в файл с именем Client.cer.

  9. В файле Client.exe.config на клиентском компьютере измените значение адреса конечной точки на соответствие новому адресу службы. Для этого замените localhost полным доменным именем сервера.

  10. Скопируйте файл Client.cer из клиентского каталога в каталог службы на сервере.

  11. На клиенте запустите ImportServiceCert.bat в командной строке разработчика для Visual Studio с правами администратора. При этом сертификат службы импортируется из файла Service.cer в хранилище CurrentUser — TrustedPeople.

  12. На сервере запустите ImportClientCert.bat в командной строке разработчика для Visual Studio с правами администратора. При этом сертификат клиента импортируется из файла Client.cer в хранилище LocalMachine — TrustedPeople.

  13. На клиентском компьютере запустите Client.exe из окна командной строки. Если клиент и служба не могут взаимодействовать, см. рекомендации по устранению неисправностей для примеров WCF.

Очистка после образца

  • Запустите Cleanup.bat в папке примеров после завершения выполнения примера.

    Заметка

    Этот скрипт не удаляет сертификаты службы на клиенте при запуске этого примера на компьютерах. Если вы запустили примеры Windows Communication Foundation (WCF), использующие сертификаты между компьютерами, не забудьте удалить сертификаты службы, установленные в хранилище CurrentUser — TrustedPeople. Для этого используйте следующую команду: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name> Например, certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com.