Шаблон для клиентов WCF Kerberos, где сервер использует учетную запись пользователя

У нас есть клиентское и сервисное приложение WCF (Windows Communication Foundation). Мы используем аутентификацию Windows с Kerberos.

Проблема в том, что служба может работать под одной из многих учетных записей (может быть, сетевой службой, может быть, конкретной учетной записью пользователя - зависит от ИТ-группы). Эта учетная запись вряд ли будет меняться ежедневно, но, возможно, время от времени (может быть, каждые несколько месяцев). Кроме того, мы доставляем этот пакет клиента/службы нескольким группам, и каждая группа может иметь свою собственную учетную запись, которую они используют для запуска службы (это просто для того, чтобы вы знали, что мы не можем сделать индивидуальное решение для одной команды). ).

Теперь причина, по которой приведенный выше абзац является проблемой, очевидно, заключается в том, что если служба не работает в учетной записи SYSTEM или NETWORK SERVICE, то есть в учетной записи пользователя, тогда клиент должен указать имя учетной записи пользователя в идентификаторе своей конечной точки.

Подробнее об этом ограничении см.: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/feb6bc31-9a4b-4f8d-a887-ef6d2c7abe41 и http://www.vistax64.com/indigo/146204-using-localhost-vs-environment-machinename.html

Теперь это, по-видимому, усложняет ситуацию, когда ИТ-отдел меняет учетную запись, на которой работает служба. Каков шаблон для обработки этого, если он есть? Как другие люди справились с этим? Одно из решений, о котором я подумал, заключается в том, что администратор отправляет электронное письмо, когда учетная запись пользователя службы изменилась, в которой есть веб-ссылка на приложение, которое обновляет клиент или файл конфигурации, поэтому клиент ссылается на новую учетную запись пользователя. . Но это кажется хакерским.

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

Кстати, это необходимо для размещения на IIS 7.0, если это имеет значение.


person Kang Su    schedule 19.07.2009    source источник


Ответы (2)


Я думаю, вы можете установить для свойства NegotiateServiceCredential значение True, поэтому ваша привязка использует SPNego вместо жесткого -cold Kerberos. Если установлено значение true, клиенту не нужно указывать имя участника-службы, и он может подключаться к серверу с немашинной учетной записью.

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

Кроме того, в качестве побочной тирады: тот факт, что WCF запрашивает имя учетной записи в качестве имени участника-службы, в основном является мозговым пердежом. Клиент должен использовать API DsMakeSpn для создания SPN из имени службы, хоста и порта. Сервер должен зарегистрировать этот SPN для себя при запуске или позволить администратору сделать это с помощью setspn.exe. Так делают все традиционные (хорошо работающие) службы в среде Kerberos/ActiveDirecotry/Windows.

Обновить

Во-вторых, я не вижу ничего, указывающего, что клиент должен использовать имя учетной записи в качестве SPN. Больше похоже на недосмотр документации, вместо того, чтобы документировать правильно, они просто рекомендовали то, что в основном является плохой практикой. Или, может быть, просто совет форума плохой, так как я не копался, чтобы увидеть, что на самом деле говорит спецификация привязки MSDN об использовании SPN...

У меня нет удобной среды WCF для тестирования, но, возможно, вы можете настроить клиентов для запроса правильного имени участника-службы, такого как YourService/server:port, и вы также зарегистрируете то же самое имя участника-службы на стороне сервера. Либо вручную, как упражнение, оставленное администраторам, либо автоматически из вашей службы при ее запуске и отмените ее регистрацию при закрытии. Правильный способ сделать это — позволить администраторам сделать это, но на самом деле это такая проблема, что большинство сервисов сами регистрируют SPN, и вы, вероятно, тоже можете следовать этой практике. Чтобы зарегистрировать SPN, ваша служба вызывает DsWriteAccountSpn. . Запись должна распространяться в AD и реплицироваться между серверами AD, и это по крайней мере одна из причин, по которой автоматическая регистрация/отмена регистрации SPN службой является сомнительной практикой.

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

Обновить

Я почти уверен, что вы можете использовать любой SPN, который вам нравится. В большинстве примеров имя учетной записи используется как «UPN» (основное имя пользователя) вместо имени участника-службы, но это сделано только для удобства примеров, поскольку использование истинного имени участника-службы приведет к административным проблемам при настройке имени участника-службы под учетной записью пользователя (опять же , зачем админам это делать...). В разделе Переопределение идентификатора службы для аутентификации релевантно подчеркивается:

По умолчанию, когда служба настроена на использование учетных данных Windows, в WSDL создается элемент, содержащий элемент <userPrincipalName> или <servicePrincipalName>. Если служба работает под учетной записью LocalSystem, LocalService или NetworkService, по умолчанию создается имя субъекта-службы (SPN) в форме host/<hostname>, поскольку эти учетные записи имеют доступ к данным SPN компьютера. Если служба работает под другой учетной записью, Windows Communication Foundation (WCF) создает имя участника-пользователя в форме <username>@<domainName>. Это происходит потому, что проверка подлинности Kerberos требует, чтобы имя участника-пользователя или участника-службы было предоставлено клиенту для проверки подлинности службы.

Вы также можете использовать средство Setspn.exe для регистрации дополнительного имени участника-службы с учетной записью службы в домене. Затем вы можете использовать имя участника-службы в качестве идентификатора службы. Чтобы загрузить это средство, см. Инструмент Windows 2000 Resource Kit: Setspn.exe. Дополнительные сведения об этом средстве см. в разделе Обзор Setspn.

person Remus Rusanu    schedule 19.07.2009
comment
Спасибо Ремус. Это выглядит хорошо. Я собираюсь изучить ваши ссылки и методы и посмотреть, работают ли они. Еще раз спасибо! - person Kang Su; 19.07.2009
comment
Кажется, это работает! Хотя я наблюдаю какое-то странное поведение. Что я сделал, так это пошел на сервер AD, запустил setspn и связал произвольный spn с учетной записью пользователя. Затем я открыл этот SPN с сервера и использовал его с клиента. Это все хорошо и хорошо. Ну, тогда я попытался изменить выставленный spn в службе и попытался использовать случайный spn от клиента. Я думал, что это должно потерпеть неудачу. Что ж, теперь, пока я указываю любой spn, он работает. Это в 10 раз лучше, чем состояние, в котором я был раньше, но было бы интересно узнать, в чем причина такого поведения. Спасибо! - person Kang Su; 19.07.2009

Установите для свойств NegotiateServiceCredential и EstablishSecurityContext значение False.

person Alex G    schedule 03.02.2010