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


Поставщик токенов

В этом примере показано, как реализовать пользовательский поставщик токенов. Поставщик токенов в Windows Communication Foundation (WCF) используется для предоставления учетных данных инфраструктуре безопасности. Поставщик токенов в целом проверяет целевой объект и выдает соответствующие учетные данные, чтобы инфраструктура безопасности могли защитить сообщение. WCF поставляется с поставщиком токенов диспетчера учетных данных по умолчанию. WCF также включает в себя провайдера токенов CardSpace. Поставщики пользовательских токенов полезны в следующих случаях:

  • Если у вас есть хранилище учетных данных, с которыми эти поставщики токенов не могут работать.

  • Если вы хотите предоставить собственный механизм для преобразования учетных данных, начиная с момента, когда пользователь вводит свои данные, и до их использования в рамках клиентской платформы WCF.

  • Если вы создаете пользовательский токен.

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

В этом примере показано следующее:

  • Как клиент может пройти проверку подлинности с помощью пары имени пользователя и пароля.

  • Как клиент может быть настроен с помощью пользовательского поставщика токенов.

  • Как сервер может проверить учетные данные клиента, используя пароль и пользовательский UserNamePasswordValidator, который подтверждает, что имя пользователя и пароль совпадают.

  • Как сервер проходит проверку подлинности клиентом с помощью сертификата X.509 сервера.

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

Служба предоставляет одну конечную точку для взаимодействия со службой, определенной с помощью файла конфигурации App.config. Конечная точка состоит из адреса, привязки и контракта. Привязка настроена с стандартной привязкой wsHttpBinding, которая использует безопасность сообщений по умолчанию. Этот пример задает стандарт wsHttpBinding для использования проверки подлинности имени пользователя клиента. Служба также настраивает сертификат службы с помощью конфигурации поведения ServiceCredentials. Функциональность serviceCredentials позволяет настроить сертификат службы. Сертификат службы используется клиентом для проверки подлинности службы и предоставления защиты сообщений. Следующая конфигурация ссылается на сертификат localhost, установленный во время примера установки, как описано в следующих инструкциях по настройке.

<system.serviceModel>
    <services>
      <service
          name="Microsoft.ServiceModel.Samples.CalculatorService"
          behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <!-- configure base address provided by host -->
            <add baseAddress ="http://localhost:8000/servicemodelsamples/service"/>
          </baseAddresses>
        </host>
        <!-- use base address provided by host -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="Binding1"
                  contract="Microsoft.ServiceModel.Samples.ICalculator" />
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="False" />
          <!--
        The serviceCredentials behavior allows one to define a service certificate.
        A service certificate is used by a client to authenticate the service and provide message protection.
        This configuration references the "localhost" certificate installed during the setup instructions.
        -->
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

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

<system.serviceModel>
  <client>
    <endpoint name=""
              address="http://localhost:8000/servicemodelsamples/service"
              binding="wsHttpBinding"
              bindingConfiguration="Binding1"
              contract="Microsoft.ServiceModel.Samples.ICalculator">
    </endpoint>
  </client>

  <bindings>
    <wsHttpBinding>
      <binding name="Binding1">
        <security mode="Message">
          <message clientCredentialType="UserName" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
</system.serviceModel>

Ниже показано, как разработать пользовательский поставщик токенов и интегрировать его с системой безопасности WCF.

  1. Напишите настраиваемый поставщик токенов.

    В данном примере реализуется настраиваемый поставщик токенов, который предоставляет имя пользователя и пароль. Пароль должен соответствовать этому имени пользователя. Этот поставщик пользовательских маркеров предназначен только для демонстрационных целей и не рекомендуется для реального развертывания.

    Для выполнения этой задачи поставщик настраиваемых маркеров наследует SecurityTokenProvider класс и переопределяет GetTokenCore(TimeSpan) метод. Этот метод создает и возвращает новое UserNameSecurityToken.

    protected override SecurityToken GetTokenCore(TimeSpan timeout)
    {
        // obtain username and password from the user using console window
        string username = GetUserName();
        string password = GetPassword();
        Console.WriteLine("username: {0}", username);
    
        // return new UserNameSecurityToken containing information obtained from user
        return new UserNameSecurityToken(username, password);
    }
    
  2. Напишите пользовательский менеджер токенов безопасности.

    SecurityTokenManager используется для создания SecurityTokenProvider для конкретного SecurityTokenRequirement, которые передаются в него методом CreateSecurityTokenProvider. Диспетчер токенов безопасности также используется для создания аутентификаторов токенов и сериализатора токенов, но они не охватываются этим примером. В этом примере пользовательский менеджер маркеров безопасности наследуется от класса ClientCredentialsSecurityTokenManager и переопределяет метод CreateSecurityTokenProvider, чтобы вернуть пользовательского поставщика маркеров имени пользователя, когда передаваемые требования к маркеру указывают на необходимость запроса поставщика имени пользователя.

    public class MyUserNameSecurityTokenManager : ClientCredentialsSecurityTokenManager
    {
        MyUserNameClientCredentials myUserNameClientCredentials;
    
        public MyUserNameSecurityTokenManager(MyUserNameClientCredentials myUserNameClientCredentials)
            : base(myUserNameClientCredentials)
        {
            this.myUserNameClientCredentials = myUserNameClientCredentials;
        }
    
        public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
        {
            // if token requirement matches username token return custom username token provider
            // otherwise use base implementation
            if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
            {
                return new MyUserNameTokenProvider();
            }
            else
            {
                return base.CreateSecurityTokenProvider(tokenRequirement);
            }
        }
    }
    
  3. Напишите пользовательские учетные данные клиента.

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

    public class MyUserNameClientCredentials : ClientCredentials
    {
        public MyUserNameClientCredentials()
            : base()
        {
        }
    
        protected override ClientCredentials CloneCore()
        {
            return new MyUserNameClientCredentials();
        }
    
        public override SecurityTokenManager CreateSecurityTokenManager()
        {
            // return custom security token manager
            return new MyUserNameSecurityTokenManager(this);
        }
    }
    
  4. Настройте клиент для использования пользовательских учетных данных клиента.

    Чтобы клиент использовал пользовательские учетные данные клиента, пример удаляет класс учетных данных клиента по умолчанию и предоставляет новый класс учетных данных клиента.

    static void Main()
    {
        // ...
           // Create a client with given client endpoint configuration
          CalculatorClient client = new CalculatorClient();
    
          // set new credentials
           client.ChannelFactory.Endpoint.Behaviors.Remove(typeof(ClientCredentials));
         client.ChannelFactory.Endpoint.Behaviors.Add(new MyUserNameClientCredentials());
       // ...
    }
    

На сервисе, чтобы отобразить сведения вызывающего абонента, используйте PrimaryIdentity, как показано в следующем примере кода. Содержит Current сведения о претензиях текущего вызывающего.

static void DisplayIdentityInformation()
{
    Console.WriteLine("\t\tSecurity context identity  :  {0}",
        ServiceSecurityContext.Current.PrimaryIdentity.Name);
}

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

Настройка пакетного файла

Пакетный файл Setup.bat, включенный в этот пример, позволяет настроить сервер с соответствующим сертификатом для запуска локального приложения, требующего безопасности на основе сертификатов сервера. Для работы этого пакетного файла на разных компьютерах или без хостинга его необходимо изменить.

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

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

    Следующие строки из пакетного файла Setup.bat создают используемый сертификат сервера. Переменная %SERVER_NAME% задает имя сервера. Измените эту переменную, чтобы указать собственное имя сервера. Значение по умолчанию в этом пакетном файле — localhost.

    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
    
  • Установка сертификата сервера в доверенное хранилище сертификатов клиента:

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

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople
    

Замечание

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

Для настройки и сборки примера

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

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

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

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

    Замечание

    Пакетный файл Setup.bat предназначен для запуска из командной строки Visual Studio. Переменная среды PATH в командной строке Visual Studio указывает на каталог, содержащий исполняемые файлы, необходимые скрипту Setup.bat.

  2. Запустите service.exe из service\bin.

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

  4. В поле ввода имени пользователя введите имя пользователя.

  5. В командной строке пароля используйте ту же строку, которая была введена для запроса имени пользователя.

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

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

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

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

  3. У вас должен быть сертификат сервера с именем субъекта, который содержит полное доменное имя компьютера. Файл Service.exe.config необходимо обновить, чтобы отразить это новое имя сертификата. Вы можете создать сертификат сервера, изменив Setup.bat пакетный файл. Обратите внимание, что файл setup.bat должен быть запущен из командной строки разработчика для Visual Studio, открытой с правами администратора. Необходимо установить переменную %SERVER_NAME% на полное имя хоста компьютера, который используется для размещения службы.

  4. Скопируйте сертификат сервера в хранилище CurrentUser-TrustedPeople клиента. Это не нужно делать, если сертификат сервера выдан доверенным издателем клиента.

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

  6. На компьютере службы запустите service.exe из командной строки.

  7. Скопируйте файлы клиентской программы из папки \client\bin\ в папку, соответствующую конкретному языку, на клиентский компьютер.

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

  9. На клиентском компьютере запустите Client.exe из окна командной строки.

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

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

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