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


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

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

Этот пример основан на примере самостоятельного хоста. Файлы конфигурации службы и клиента такие же, как у примера Self-Host.

Замечание

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

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

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public double Add(double n1, double n2)
{
    double result = n1 + n2;
    Console.WriteLine("Received Add({0},{1})", n1, n2);
    Console.WriteLine("Return: {0}", result);
    DisplayIdentityInformation();
    return result;
}

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

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

static void DisplayIdentityInformation()
{
    Console.WriteLine("\t\tThread Identity            :{0}",
         WindowsIdentity.GetCurrent().Name);
    Console.WriteLine("\t\tThread Identity level  :{0}",
         WindowsIdentity.GetCurrent().ImpersonationLevel);
    Console.WriteLine("\t\thToken                     :{0}",
         WindowsIdentity.GetCurrent().Token.ToString());
    return;
}

Метод Subtract службы олицетворяет вызывающий объект с помощью императивных вызовов, как показано в следующем примере кода.

public double Subtract(double n1, double n2)
{
    double result = n1 - n2;
    Console.WriteLine("Received Subtract({0},{1})", n1, n2);
    Console.WriteLine("Return: {0}", result);
    Console.WriteLine("Before impersonating");
    DisplayIdentityInformation();

    if (ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Impersonation ||
        ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Delegation)
    {
        // Impersonate.
        using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
        {
            // Make a system call in the caller's context and ACLs
            // on the system resource are enforced in the caller's context.
            Console.WriteLine("Impersonating the caller imperatively");
            DisplayIdentityInformation();
        }
    }
    else
    {
        Console.WriteLine("ImpersonationLevel is not high enough to perform this operation.");
    }

    Console.WriteLine("After reverting");
    DisplayIdentityInformation();
    return result;
}

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

Другие методы не имитируют вызывающего.

Клиентский код был изменен, чтобы задать уровень Impersonationолицетворения равным. Клиент указывает уровень олицетворения, который будет использоваться службой, используя перечисление TokenImpersonationLevel. Перечисление поддерживает следующие значения: None, Anonymous, IdentificationImpersonation и Delegation. Чтобы выполнить проверку доступа при обращении к системному ресурсу на локальном компьютере, защищенному с помощью списков управления доступом (ACL) Windows, уровень олицетворения должен быть установлен на Impersonation, как показано в следующем образце кода.

// Create a client with given client endpoint configuration
CalculatorClient client = new CalculatorClient();

client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

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

Замечание

Служба должна либо выполняться под учетной записью администратора, либо учетной записи, под которой она работает, должны быть предоставлены права на регистрацию URI http://localhost:8000/ServiceModelSamples в HTTP-слое. Такие права можно предоставить, настроив резервирование пространства имен с помощью средстваHttpcfg.exe.

Замечание

На компьютерах под управлением Windows Server 2003 олицетворение поддерживается только в том случае, если у приложения Host.exe есть права олицетворения. (По умолчанию только администраторы имеют это разрешение.) Чтобы добавить эту привилегию в учетную запись, под которой работает служба, перейдите к средствам администрирования, откройте локальную политику безопасности, откройте локальные политики, щелкните Назначение прав пользователя и выберите Олицетворение клиента после аутентификации, а затем дважды щелкните Свойства, чтобы добавить пользователя или группу.

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

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

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

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

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

    runas /user:<machine-name>\<user-name> client.exe
    

    Затем появится запрос на ввод пароля. Введите пароль для указанной ранее учетной записи.

  5. При запуске клиента запишите удостоверение до и после запуска с различными учетными данными.