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


Делегирование и олицетворение с помощью WCF

Олицетворение — это распространенный метод, используемый службами для ограничения доступа клиента к ресурсам домена службы. Ресурсы домена службы могут быть системными ресурсами, такими как локальные файлы (имитация от лица пользователя), или ресурсами на другом компьютере, такими как совместно используемый ресурс (делегирование). Пример приложения см. в разделе олицетворение клиента. Пример использования имперсонации см. в статье "Практическое руководство: Олицетворение клиента в службе".

Это важно

Помните, что при выполнении входа от имени клиента в службу, служба работает с учетными данными клиента, что может предоставить более высокий уровень доступа, чем у процесса сервера.

Обзор

Как правило, клиенты вызывают службу, чтобы служба выполняла некоторые действия от имени клиента. Олицетворение позволяет службе выступать в качестве клиента при выполнении действия. Делегирование позволяет интерфейсной службе перенаправлять запрос клиента в серверную службу таким образом, чтобы серверная служба также может олицетворить клиента. Олицетворение чаще всего используется как способ проверки того, разрешен ли клиент выполнять определенное действие, а делегирование — это способ передачи возможностей олицетворения, а также удостоверения клиента в серверную службу. Делегирование — это функция домена Windows, которую можно использовать при выполнении проверки подлинности на основе Kerberos. Делегирование отличается от потока идентификаций, так как делегирование передает возможность олицетворения клиента без владения паролем клиента, это более высокопривилегированная операция, чем идентификационный поток.

Как для имитации, так и для делегирования требуется, чтобы у клиента было удостоверение Windows. Если клиент не обладает удостоверением Windows, единственный вариант — передавать удостоверение клиента во вторую службу.

Основы олицетворения

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

В этом разделе рассматриваются олицетворение и делегирование в WCF при использовании безопасности SOAP. Вы также можете использовать олицетворение и делегирование с WCF при использовании безопасности транспорта, как описано в разделе "Использование олицетворения с безопасностью транспорта".

Два метода

Безопасность SOAP WCF имеет два различных метода для выполнения олицетворения. Используемый метод зависит от привязки. Одним из них является использование учетных данных с использованием токена Windows, полученного через интерфейс поставщика поддержки безопасности (SSPI) или аутентификация Kerberos, которые затем кэшируются в службе. Второй вариант — имитация из маркера Windows, полученного из расширений Kerberos, коллективно называемых «Служба для пользователя» (S4U).

Олицетворение кэшированного токена

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

  • WSHttpBinding, WSDualHttpBindingи NetTcpBinding с учетными данными клиента Windows.

  • BasicHttpBinding BasicHttpSecurityMode TransportWithMessageCredential с заданными учетными данными или любой другой стандартной привязкой, в которой клиент представляет учетные данные имени пользователя, которые служба может сопоставить с допустимой учетной записью Windows.

  • Любой CustomBinding , использующий учетные данные клиента Windows с заданным значением requireCancellationtrue. (Свойство доступно в следующих классах: SecureConversationSecurityTokenParameters, SslSecurityTokenParameters, и SspiSecurityTokenParameters.) Если для привязки используется безопасная беседа, то она также должна иметь свойство requireCancellation, установленное на true.

  • Любой CustomBinding, где клиент предоставляет учетные данные пользователя. Если для привязки используется защищенный разговор, также должно быть установлено свойство requireCancellation значение true.

S4U-Based Имитация

Вы можете выполнить олицетворение на основе S4U при помощи следующего:

  • WSHttpBinding, WSDualHttpBindingи NetTcpBinding с учетными данными клиента сертификата, которые служба может сопоставить с допустимой учетной записью Windows.

  • Любой CustomBinding, использующий учетные данные клиента Windows со свойством requireCancellation, установленным в false.

  • Любой CustomBinding, использующий имя пользователя или учетные данные клиента Windows и безопасный обмен данными с заданным свойством requireCancellation на false.

Способность службы олицетворять клиента зависит от привилегий учетной записи службы при попытке имперсонации, типа имперсонации, которое используется, и, возможно, в степени, в которой клиент это разрешает.

Замечание

Когда клиент и служба выполняются на том же компьютере, и клиент работает под системной учетной записью (например, Local System или Network Service), клиент не может быть олицетворен при установке безопасного сеанса с маркерами контекста безопасности с отслеживанием состояния. Приложение Windows Form или консольное приложение обычно выполняется под учетной записью текущего пользователя, чтобы по умолчанию можно было имитировать эту запись. Однако, если клиент является страницей ASP.NET и эта страница размещается в IIS 6.0 или IIS 7.0, то клиент запускается именно под учетной записью Network Service по умолчанию. Все предоставленные системой привязки, поддерживающие безопасные сеансы, используют маркер контекста безопасности без сохранения состояния (SCT) по умолчанию. Однако, если клиентом является страница ASP.NET, и используются безопасные сеансы с использованием SCT с отслеживанием состояния, клиент не может быть олицетворен. Дополнительные сведения об использовании SCTs с отслеживанием состояния в безопасном сеансе см. в разделе "Практическое руководство. Создание токена контекста безопасности для безопасного сеанса".

Олицетворение в методе службы: декларативная модель

Большинство сценариев олицетворения включают выполнение метода службы в контексте вызывающего объекта. WCF предоставляет функцию олицетворения, которая упрощает эту задачу, позволяя пользователю указывать требование олицетворения в атрибуте OperationBehaviorAttribute . Например, в следующем коде инфраструктура WCF имитирует вызывающего перед выполнением метода Hello. Любая попытка доступа к собственным ресурсам в методе Hello выполнена успешно, только если список управления доступом (ACL) ресурса разрешает доступ вызывающего абонента к привилегиям. Чтобы включить олицетворение, установите свойство Impersonation на одно из значений перечисления ImpersonationOption, например ImpersonationOption.Required или ImpersonationOption.Allowed, как показано в следующем примере.

Замечание

Если у службы учетные данные выше, чем у удаленного клиента, используются учетные данные службы, если для свойства Impersonation задано значение Allowed. То есть, если пользователь с низким уровнем привилегий предоставляет свои учетные данные, служба с более высоким уровнем привилегий выполняет метод с учетными данными службы и может использовать ресурсы, которые пользователь с низким уровнем привилегий не сможет использовать.

[ServiceContract]
public interface IHelloContract
{
    [OperationContract]
    string Hello(string message);
}

public class HelloService : IHelloService
{
    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string Hello(string message)
    {
        return "hello";
    }
}

<ServiceContract()> _
Public Interface IHelloContract
    <OperationContract()> _
    Function Hello(ByVal message As String) As String
End Interface


Public Class HelloService
    Implements IHelloService

    <OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
    Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
        Return "hello"
    End Function
End Class

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

Замечание

В Windows XP имперсонификация завершается ошибкой при создании SCT с отслеживанием состояния, что вызывает InvalidOperationException. Дополнительные сведения см. в разделе " Неподдерживаемые сценарии".

Олицетворение в методе службы: императивная модель

Иногда вызывающему абоненту не нужно имитировать весь пакет служб для выполнения функции, а только часть. В этом случае получите удостоверение вызывающего объекта Windows внутри метода службы и императивно выполните олицетворение. Для этого используйте свойство WindowsIdentity объекта ServiceSecurityContext, чтобы вернуть экземпляр класса WindowsIdentity, и вызовите метод Impersonate перед использованием экземпляра.

Замечание

Не забудьте использовать инструкцию Visual BasicUsing или оператор C# using , чтобы автоматически вернуть действие олицетворения. Если вы не используете инструкцию или используете язык программирования, отличный от Visual Basic или C#, обязательно верните уровень олицетворения. Неспособность сделать это может быть основой для отказов в обслуживании и повышения привилегий.

public class HelloService : IHelloService
{
    [OperationBehavior]
    public string Hello(string message)
    {
        WindowsIdentity callerWindowsIdentity =
        ServiceSecurityContext.Current.WindowsIdentity;
        if (callerWindowsIdentity == null)
        {
            throw new InvalidOperationException
           ("The caller cannot be mapped to a WindowsIdentity");
        }
        using (callerWindowsIdentity.Impersonate())
        {
            // Access a file as the caller.
        }
        return "Hello";
    }
}
Public Class HelloService
    Implements IHelloService

    <OperationBehavior()> _
    Public Function Hello(ByVal message As String) As String _
       Implements IHelloService.Hello
        Dim callerWindowsIdentity As WindowsIdentity = _
            ServiceSecurityContext.Current.WindowsIdentity
        If (callerWindowsIdentity Is Nothing) Then
            Throw New InvalidOperationException( _
              "The caller cannot be mapped to a WindowsIdentity")
        End If
        Dim cxt As WindowsImpersonationContext = callerWindowsIdentity.Impersonate()
        Using (cxt)
            ' Access a file as the caller.
        End Using

        Return "Hello"

    End Function
End Class

Олицетворение для всех методов службы

В некоторых случаях необходимо выполнить все методы сервиса в контексте вызывающего. Вместо явного включения этой функции на основе каждого метода используйте этот ServiceAuthorizationBehaviorпараметр. Как показано в следующем коде, установите значение свойства ImpersonateCallerForAllOperations на true. ServiceAuthorizationBehavior извлекается из коллекций поведения класса ServiceHost. Кроме того, обратите внимание, что Impersonation свойство примененного OperationBehaviorAttribute к каждому методу также должно иметь значение Allowed или Required.

// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthorizationBehavior =
    serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = true;
' Code to create a ServiceHost not shown.
Dim MyServiceAuthorizationBehavior As ServiceAuthorizationBehavior
MyServiceAuthorizationBehavior = serviceHost.Description.Behaviors.Find _
(Of ServiceAuthorizationBehavior)()
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = True

В следующей таблице описано поведение WCF для всех возможных сочетаний ImpersonationOption и ImpersonateCallerForAllServiceOperations.

ImpersonationOption ImpersonateCallerForAllServiceOperations Поведение
Обязательно n/a WCF олицетворяет вызывающего абонента
Допустимо неправда WCF не олицетворяет вызывающего абонента
Допустимо правда WCF олицетворяет вызывающего абонента
Не разрешено неправда WCF не олицетворяет вызывающего абонента
Не разрешено правда Запрещено. (Вызывается InvalidOperationException .)

Уровень олицетворения, полученный из учетных данных Windows и олицетворения кэшированного токена

В некоторых сценариях клиент имеет частичный контроль над уровнем олицетворения службы, выполняемой при использовании учетных данных клиента Windows. Один из сценариев возникает, когда клиент задает уровень анонимной олицетворения. Другой возникает при выполнении олицетворения с кэшируемым токеном. Это делается путем задания AllowedImpersonationLevel свойства WindowsClientCredential класса, доступ к которому осуществляется в качестве свойства универсального ChannelFactory<TChannel> класса.

Замечание

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

Клиент может указать уровень олицетворения как Anonymous, Identification, Impersonationили Delegation. Создается только токен на указанном уровне, как показано в следующем коде.

ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel  =
    System.Security.Principal.TokenImpersonationLevel.Impersonation;
Dim cf As ChannelFactory(Of IEcho) = New ChannelFactory(Of IEcho)("EchoEndpoint")
cf.Credentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Impersonation

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

Значение AllowedImpersonationLevel Служба имеет SeImpersonatePrivilege Служба и клиент способны делегировать. Кэшированный токен ImpersonationLevel
Анонимный Да n/a Олицетворение
Анонимный нет n/a Идентификация
Идентификация n/a n/a Идентификация
Олицетворение Да n/a Олицетворение
Олицетворение нет n/a Идентификация
Делегирование Да Да Делегирование
Делегирование Да нет Олицетворение
Делегирование нет n/a Идентификация

Уровень олицетворения, полученный из учетных данных имени пользователя и олицетворения кэшированного токена

Передавая службе имя пользователя и пароль, клиент позволяет WCF входить в систему от имени этого пользователя, что эквивалентно установке свойства AllowedImpersonationLevel в Delegation. (Доступно AllowedImpersonationLevel в WindowsClientCredential и HttpDigestClientCredential классах.) В следующей таблице представлен уровень олицетворения, полученный при получении учетных данных имени пользователя.

AllowedImpersonationLevel Служба имеет SeImpersonatePrivilege Служба и клиент способны делегировать. Кэшированный токен ImpersonationLevel
n/a Да Да Делегирование
n/a Да нет Олицетворение
n/a нет n/a Идентификация

Уровень олицетворения, полученный из имитации S4U-Based

Служба имеет SeTcbPrivilege Служба имеет SeImpersonatePrivilege Служба и клиент способны делегировать. Кэшированный токен ImpersonationLevel
Да Да n/a Олицетворение
Да нет n/a Идентификация
нет n/a n/a Идентификация

Сопоставление сертификата клиента с учетной записью Windows

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

<behaviors>  
  <serviceBehaviors>  
    <behavior name="MapToWindowsAccount">  
      <serviceCredentials>  
        <clientCertificate>  
          <authentication mapClientCertificateToWindowsAccount="true" />  
        </clientCertificate>  
      </serviceCredentials>  
    </behavior>  
  </serviceBehaviors>  
</behaviors>  

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

// Create a binding that sets a certificate as the client credential type.  
WSHttpBinding b = new WSHttpBinding();  
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;  
  
// Create a service host that maps the certificate to a Windows account.  
Uri httpUri = new Uri("http://localhost/Calculator");  
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);  
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;  

Делегирование

Чтобы делегировать серверную службу, служба должна выполнять многоуровневую проверку подлинности Kerberos (SSPI без резервного копирования NTLM) или Kerberos прямую проверку подлинности в серверную службу с помощью удостоверения Windows клиента. Чтобы делегировать бэкэнд-сервису, создайте ChannelFactory<TChannel> и канал, а затем обменивайтесь данными через этот канал от имени клиента. При такой форме делегирования расстояние, на котором серверная служба может находиться от фронтенд-службы, зависит от уровня олицетворения, достигнутого фронтенд-службой. Если уровень воплощения равен Impersonation, фронтенд и бэкенд службы должны работать на одном компьютере. Если уровень имперсонации равен Delegation, фронтальные и серверные службы могут находиться на разных серверах или на одном сервере. Включение олицетворения на уровне делегирования требует, чтобы политика домена Windows была настроена для разрешения делегирования. Дополнительные сведения о настройке Active Directory для поддержки делегирования см. в разделе "Включение делегированной проверки подлинности".

Замечание

Когда клиент проходит проверку подлинности в интерфейсной службе, используя имя пользователя и пароль, соответствующие учетной записи Windows в серверной службе, интерфейсная служба может пройти проверку подлинности в серверной службе, повторно используя имя пользователя и пароль клиента. Это особенно мощная форма потока удостоверений, поскольку передача имени пользователя и пароля внутренней службе позволяет выполнять имитирование пользователя, но это не представляет собой делегирование, так как Kerberos не используется. Элементы управления Active Directory для делегирования не применяются к имени пользователя и проверке подлинности паролей.

Способность делегирования как функция степени уровня олицетворения

Уровень олицетворения Служба может выполнять делегирование между процессами Служба может выполнять делегирование между компьютерами
Identification нет нет
Impersonation Да нет
Delegation Да Да

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

public class HelloService : IHelloService
{
    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string Hello(string message)
    {
        WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
        if (callerWindowsIdentity == null)
        {
            throw new InvalidOperationException
             ("The caller cannot be mapped to a Windows identity.");
        }
        using (callerWindowsIdentity.Impersonate())
        {
            EndpointAddress backendServiceAddress = new EndpointAddress("http://localhost:8000/ChannelApp");
            // Any binding that performs Windows authentication of the client can be used.
            ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
            IHelloService channel = channelFactory.CreateChannel();
            return channel.Hello(message);
        }
    }
}
Public Class HelloService
    Implements IHelloService

    <OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
    Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
        Dim callerWindowsIdentity As WindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity
        If (callerWindowsIdentity Is Nothing) Then
            Throw New InvalidOperationException("The caller cannot be mapped to a Windows identity.")
        End If

        Dim backendServiceAddress As EndpointAddress = New EndpointAddress("http://localhost:8000/ChannelApp")
        ' Any binding that performs Windows authentication of the client can be used.
        Dim channelFactory As ChannelFactory(Of IHelloService) = _
          New ChannelFactory(Of IHelloService)(New NetTcpBinding(), backendServiceAddress)
        Dim channel As IHelloService = channelFactory.CreateChannel()
        Return channel.Hello(message)
    End Function
End Class

Настройка приложения для использования ограниченного делегирования

Прежде чем использовать ограниченное делегирование, отправитель, получатель и контроллер домена должны быть настроены для этого. В следующей процедуре описаны шаги, которые позволяют осуществить ограниченное делегирование. Для получения подробной информации о различиях между делегированием и ограниченным делегированием см. раздел расширений Kerberos Windows Server 2003, посвященный ограниченному делегированию.

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

  2. На контроллере домена установите флажок «Учетная запись доверена для делегирования» для учетной записи, под которой выполняется клиентское приложение.

  3. На контроллере домена настройте компьютер среднего уровня так, чтобы он был доверенным для делегирования, нажав Доверять компьютер для делегирования.

  4. На контроллере домена настройте компьютер среднего уровня для использования ограниченного делегирования, выбрав опцию Доверять этому компьютеру для делегирования только указанным службам.

Дополнительные инструкции по настройке ограниченного делегирования см. в разделе "Переход протокола Kerberos" и "Ограниченное делегирование".

См. также