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


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

Олицетворение — это стандартная техника, которую службы используют для ограничения клиентского доступа к ресурсам домена службы. В роли ресурсов домена службы могут выступать ресурсы компьютера, например локальные файлы (олицетворение), или ресурсы, расположенные на другом компьютере, например общая папка (делегирование). Образец приложения см. в разделе Impersonating the Client. Пример использования олицетворения см. в разделе Как олицетворять клиент в рамках службы.

ms730088.Important(ru-ru,VS.100).gif Примечание
Следует иметь в виду, что при олицетворении клиента в службе служба выполняется с учетными данными клиента, которые могут иметь более высокий уровень разрешений, чем серверный процесс.

Общие сведения

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

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

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

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

Основной акцент в этом разделе делается на олицетворении и делегировании в WCF при использовании механизма безопасности SOAP. Олицетворение и делегирование в WCF также можно использовать при реализации безопасности транспорта, как описано в разделе Использование олицетворения при обеспечении безопасности транспорта.

Два метода

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

Олицетворение с использованием кэшированного маркера

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

  • привязки WSHttpBinding, WSDualHttpBinding и NetTcpBinding, а также учетные данные клиента Windows;

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

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

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

Олицетворение на базе S4U

Для олицетворения на базе S4U используются следующие элементы:

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

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

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

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

ms730088.note(ru-ru,VS.100).gifПримечание
Если клиент и служба выполняются на одном компьютере и клиент выполняется от имени системной учетной записи (например, Local System или Network Service), клиент невозможно олицетворить, если установлен безопасный сеанс с маркерами контекста безопасности с отслеживанием состояния. Приложения Windows Form и консольные приложения обычно выполняются от имени учетной записи находящегося в системе пользователя, поэтому эту учетную запись можно олицетворять по умолчанию. Если же клиент представляет собой страницу ASP.NET, которая размещена в службах IIS 6,0 или IIS 7.0, то клиент по умолчанию выполняется от имени учетной записи Network Service. Все предоставляемые системой привязки, поддерживающие защищенные сеансы, по умолчанию используют маркеры контекста безопасности с отслеживанием состояния. Но если клиент является страницей ASP.NET и используются защищенные сеансы с маркерами контекста безопасности с отслеживанием состояния, олицетворить клиент невозможно. Дополнительные сведения использовании маркеров контекста безопасности с отслеживанием состояния в защищенном сеансе см. в разделе Как создать маркер контекста безопасности с отслеживанием состояния для безопасного сеанса.

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

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

ms730088.note(ru-ru,VS.100).gifПримечание
Если у службы имеется больше прав, чем у удаленного клиента, то используются учетные данные службы, если свойство Impersonation имеет значение Allowed. Это значит, что если пользователь с более узкими правами предоставляет свои учетные данные, то метод выполняется с более широкими правами службы, и пользователь получает доступ к ресурсам, доступ к которым он бы сам получить не смог.

<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 
[ServiceContract]
public interface IHelloContract
{
    [OperationContract]
    string Hello(string message);
}

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

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

ms730088.note(ru-ru,VS.100).gifПримечание
В Windows XP происходит сбой олицетворения, если создается маркер контекста безопасности с отслеживанием состояния, что приводит к появлению исключения InvalidOperationException. Дополнительные сведения см. в разделе Неподдерживаемые сценарии.

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

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

ms730088.note(ru-ru,VS.100).gifПримечание
Для автоматической отмены действия олицетворения следует воспользоваться оператором Using в Visual Basic или using в C#. Если этот оператор не используется или если используется язык программирования, отличный от Visual Basic и C#, необходимо обязательно вернуть прежний уровень олицетворения. В противном случае возникнет угроза атаки типа «отказ в обслуживании» или «несанкционированное получение прав».

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 
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";
    }
}

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

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

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

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

ImpersonationOption ImpersonateCallerForAllServiceOperations Поведение

Required

не применяется

WCF олицетворяет вызывающий объект

Allowed

false

WCF не олицетворяет вызывающий объект

Allowed

true

WCF олицетворяет вызывающий объект

NotAllowed

false

WCF не олицетворяет вызывающий объект

NotAllowed

true

Disallowed. (Создается исключение InvalidOperationException.)

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

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

ms730088.note(ru-ru,VS.100).gifПримечание
Задание уровня олицетворения Anonymous приводит к тому, что клиент входит в систему службы анонимно. Поэтому служба должна разрешать анонимный вход независимо от того, будет ли выполняться олицетворение.

Клиент может установить один из следующих уровней олицетворения: Anonymous, Identification, Impersonation или Delegation. При этом создается только маркер на заданном уровне, как показано в следующем фрагменте кода.

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

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

Значение AllowedImpersonationLevel У службы есть SeImpersonatePrivilege Служба и клиент поддерживают делегирование Кэшированный маркер ImpersonationLevel

Anonymous

Да

не применяется

Impersonation

Anonymous

Нет

не применяется

Identification

Identification

не применяется

не применяется

Identification

Impersonation

Да

не применяется

Impersonation

Impersonation

Нет

не применяется

Identification

Delegation

Да

Да

Delegation

Delegation

Да

Нет

Impersonation

Delegation

Нет

не применяется

Identification

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

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

AllowedImpersonationLevel У службы есть SeImpersonatePrivilege Служба и клиент поддерживают делегирование Кэшированный маркер ImpersonationLevel

не применяется

Да

Да

Delegation

не применяется

Да

Нет

Impersonation

не применяется

Нет

не применяется

Identification

Уровень олицетворения при олицетворении на базе S4U

У службы есть SeTcbPrivilege У службы есть SeImpersonatePrivilege Служба и клиент поддерживают делегирование Кэшированный маркер ImpersonationLevel

Да

Да

не применяется

Impersonation

Да

Нет

не применяется

Identification

Нет

не применяется

не применяется

Identification

Сопоставление сертификата клиента с учетной записью 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("https://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;

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

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

ms730088.note(ru-ru,VS.100).gifПримечание
Если клиент проходит проверку подлинности во внешней службе с использованием имени пользователя и пароля, соответствующих учетной записи Windows во внутренней службе, внешняя служба может пройти проверку подлинности во внутренней службе, используя имя пользователя и пароль клиента. Это особенно мощная форма передачи удостоверений, поскольку передача имени пользователя и пароля внутренней службе позволяет этой службе выполнять олицетворение; однако в этом случае невозможно делегирование, т. к. не используется проверка подлинности Kerberos. Действие элементов управления делегированием службы каталогов Active Directory не распространяется на проверку подлинности имени пользователя и пароля.

Возможность делегирования как функция уровня олицетворения

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

Identification

Нет

Нет

Impersonation

Да

Нет

Delegation

Да

Да

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

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("https://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
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("https://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);
        }
    }
}

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

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

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

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

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

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

Более подробные инструкции по настройке ограниченного делегирования см. в следующих разделах MSDN:

См. также

Задачи

Impersonating the Client
Как олицетворять клиент в рамках службы

Справочник

OperationBehaviorAttribute
Impersonation
ImpersonationOption
WindowsIdentity
ServiceSecurityContext
WindowsIdentity
ServiceAuthorizationBehavior
ImpersonateCallerForAllOperations
ServiceHost
AllowedImpersonationLevel
WindowsClientCredential
ChannelFactory
Identification

Основные понятия

Использование олицетворения при обеспечении безопасности транспорта
Служебное средство ServiceModel Metadata Utility Tool (Svcutil.exe)