Какое TargetName использовать при вызове InitializeSecurityContext (Negotiate)? - PullRequest
18 голосов
/ 20 марта 2012

Вопрос

При вызове InitializeSecurityContext, какое значение я передаю параметру TargetName?

Пересмотренный фон

Iвызываю функцию InitializeSecurityContext:

InitializeSecurityContextA(
      @pAS.hcred,           //[in] credentials
      phContext,            //[in] optional] Context handle structure
      pszTargetName,        //[in, optional] Target name
      0,                    //[in] context requirements
      0,                    //[in] reserved1, must be zero
      SECURITY_NATIVE_DREP, //[in] target data representation
      pInput,               //[in] optional] SecBufferDescription
      0,                    //[in] reserved2, must be zero
      @pAS.hctxt,           //[in, out] pointer to context handle structure
      @OutBuffDesc,         //[in, out] pointer to SecBufferDesc
      ContextAttributes,    //[out] context attributes
      @lifetime);           //[out] expiration timestamp

Что мне передать pszTargetName?

Я пробовал

  • null: InitializeSecurityContextA(@pAS.hcred, phContext, null, ...);
  • "": InitializeSecurityContextA(@pAS.hcred, phContext, "", ...);
  • "spn/HOSTNAME":InitializeSecurityContextA(@pAS.hcred, phContext, "spn/HOSTNAME", ...);
  • spn/HOSTNAME.DOMAIN.COM: InitializeSecurityContextA(@pAS.hcred, phContext, "spn/HOSTNAME.DOMAIN.COM", ...);
  • "cargocult/PROGRAMMING": InitializeSecurityContextA(@pAS.hcred, phContext, "cargocult/PROGRAMMING", ...);
  • "http/TFS.DOMAIN.COM": InitializeSecurityContextA(@pAS.hcred, phContext, "http/TFS.DOMAIN.COM", ...);
  • "http/HOSTNAME": InitializeSecurityContextA(@pAS.hcred, phContext, "http/HOSTNAME", ...);
  • "qwertyasdf": InitializeSecurityContextA(@pAS.hcred, phContext, "qwertyasdf", ...);

  • "AuthSamp": InitializeSecurityContextA(@pAS.hcred, phContext, "AuthSamp", ...);

Все они либо терпят неудачу, либо переходят на NTLM.

Примечание : Моя машина подключена к домену, но домен не с именем domain.com, или даже hostname.domain.com, или даже qwertyasdf.Поэтому я не удивлен, что эти попытки провалились.Но люди говорили, что попробуйте что-то вроде http/HOSTNAME, поэтому я вставил http/HOSTNAME.

Фон

InitializeSecurityContext (переговоры) имеет функцию необязательный TargetName параметр:

pszTargetName [in, необязательно]

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

Что это должно быть?

Дополнительные сведения

Я пытаюсь проверить набор учетных данных пользователя, например:

Boolean ValidateCredentials(String username, String password, String domain)
{
   ...
}

Для проверки набора учетных данных пользователя необходимо использовать API SSPI.Первая функция для вызова - InitializeSecurityContext.Одним из параметров InitializeSecurityContext является "TargetName" string.

Я пытался оставить его null , но Application Verifier запускает точку останова, выписывая ошибку:

ОСТАНОВКА ВЕРЬЕРА 00005003: pid 0xF08:
InitializeSecurityContext использует целевую или недействительную цель для службы Kerberos.
Пожалуйста, смотрите значение pszTargetName для pszTargetNameцель.
00000000: не используется.
00000000: не

На этом этапе полезно помнить, что поставщик Negotiate попытается использовать Kerberos, ноотступление к NTLM.В случае Negotiate, Kerberos или NTLM параметр TargetName задокументирован как :

Имя участника службы (SPN) или контекст безопасности конечного сервера.

Но что тогда мне передавать?

я попытался сделать то, что делает статья базы знаний SSPI, ничего (т.е. передать NULL):

Как проверить учетные данные пользователя в операционных системах Microsoft

ss = _InitializeSecurityContext(
        &pAS->hcred,
        pAS->fInitialized ? &pAS->hctxt : NULL, 
        NULL,        //<-------pszTargetName
        0, 
        0,
        SECURITY_NATIVE_DREP, 
        pAS->fInitialized ? &sbdIn : NULL,
        0, 
        &pAS->hctxt, 
        &sbdOut, 
        &fContextAttr, 
        &tsExpiry);

Но ничего (т.е. NULL) не работает.

Примечание: Статья KB была массово переписана в 2007 году. В своем первоначальном воплощении 1999 года они передали "AuthSamp" в качестве цели, но это также не удалось.

Bonus Chatter:

имя участника службы
(SPN) Имя, по которому клиент однозначно идентифицирует экземпляр службы.Если вы устанавливаете несколько экземпляров службы на компьютерах по всему лесу, у каждого экземпляра должен быть свой собственный SPN.У данного экземпляра службы может быть несколько SPN, если есть несколько имен, которые клиенты могут использовать для аутентификации

контекст безопасности
Атрибуты или правила безопасности, которые действуют в настоящее время.Например, текущий пользователь вошел в систему на компьютере или персональный идентификационный номер, введенный пользователем смарт-карты.Для SSPI контекст безопасности - это непрозрачная структура данных, которая содержит данные безопасности, относящиеся к соединению, такие как ключ сеанса или указание продолжительности сеанса.

Бонус Chatter 2

Из документации для верификатора приложения:

Плагин Verifier обнаруживает следующие ошибки:

  • Пакет NTLM напрямую указывается в вызове AcquireCredentialsHandle (или более высокий уровень API оболочки).

  • Целевое имя в вызове InitializeSecurityContext - NULL.

  • Целевое имя в вызове InitializeSecurityContext не является правильно сформированным доменным именем в стиле SPN, UPN или NetBIOS.

  • Последние два случая заставят Negotiate вернуться к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «принципал не найден» во втором случае)ведение переговоров к отступлению).

  • Плагин также регистрирует предупреждения при обнаружении перехода на NTLM;например, когда SPN не найден контроллером домена.Они регистрируются только как предупреждения, поскольку они часто являются законными случаями - например, при аутентификации в системе, которая не присоединена к домену.

В моем случае домен я являюсьпроверка на соответствие null (так как я не знаю доменное имя машины, или даже если является доменом).Но результаты будут такими же, если жестко закодировать доменное имя моей машины разработки.

Обновление 3

Значения pszTargetName , которые вызывают ошибку AppVerifier, но вход в систему завершается успешно :

  • null
  • ""
  • "AuthSamp"
  • "qwertyasdf"
  • * имя домена, с которым я проверяю (например, "avatopia.com")
  • * имя домена, к которому присоединен компьютер (например, "avatopia.com")
  • * имя домена, в котором находится учетная запись пользователя (например, "avatopia.com")

Значения pszTargetName , которые не вызывают ошибку AppVerifier, но входят в систему не удается :

  • "http/HOSTNAME"
  • "http/TFS.DOMAIN.COM"
  • "frob/GROBBER"
  • "cargocult/PROGRAMMING"
  • "spn/HOSTNAME"
  • "spn/HOSTNAME.DOMAIN.COM"

Значения pszTargetname , которые не вызывают ошибку AppVerifier, и вход в систему завершается успешно:

  • нет

Обновление 4

WЧто я пытаюсь сделать: выяснить, если имя пользователя / пароль действительны.

  • У меня есть имя пользователя: например, "ian"
  • У меня есть пароль: например, "pass1"

Теперь есть еще один недостаток, что учетная записьian может быть локальной учетной записью или domain учетной записью.И вам нужно решить, является ли ian локальной или доменной учетной записью, прежде чем вы сможете спросить.Это связано с тем, что ian может иметь двух учетных записей:

  • ian в домене stackoverflow.com
  • ian на локальном компьютере

Поэтому мне нужно указать, хочу ли я:

  • задать конкретный домен (например, stackoverflow.com) или
  • задать локальный компьютер (который я 'll представляет как ".")

Теперь мы можем создать перекрестную ссылку:

Username  Password  Domain             Machine on domain?  Validate as
========  ========  =================  ==================  ==============
iboyd     pass1     .                  No                  Local account
iboyd     pass1     (empty)            No                  Local account
iboyd     pass1     stackoverflow.com  No                  Domain account

iboyd     pass1     .                  Yes                 Local account
iboyd     pass1     (empty)            Yes                 Domain account
iboyd     pass1     stackoverflow.com  Yes                 Domain account

Обновление 5

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

enter image description here

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

TURBOENCABULATOR\ian

Примечание: Я очень сомневаюсь, что в сети есть домен с именем turboencabulator, поскольку само название происходит только от от автоматизации Rockwell .Попытка входа в систему почти , безусловно, не удастся.Но как Windows проверяет их?

Как Windows пытается проверить эти учетные данные?Как Windows проверяет учетные данные:

  • Имя пользователя : ian
  • Пароль : pass1
  • Домен : TURBOENCABULATOR

Делает Windows использовать Интерфейс пакета поддержки безопасности ? Если Windows использует Согласовать или Kerberos для аутентификации, что Windows передается в качестве параметра pszTarget?Почти наверняка введенные мной учетные данные не будут действительными.Как Windows определит, действительны ли они?Какой API будет Windows вызывать для проверки учетных данных?

Windows может проверять учетные данные. Я хочу также проверить учетные данные.

Возможно, вместо того, чтобы пытаться подключиться к домену TURBOENCABULATOR, я пытаюсь подключиться к домену turboencabulator.com, предварительно добавивдомен для моего имени пользователя как turboencabulator.com\ian:

enter image description here

Тот же вопрос применим.Как Windows проверяет учетные данные?Я хочу сделать то, что делает Windows.Предполагая, что Windows использует Kerberos для авторизации, что Windows передает в качестве параметра pszTargetName в SSPI?

Возможно, вместо попытки подключиться к домену turboencabulator.com, я пытаюсь подключиться к домену turboencabulator.net:

enter image description here

Обратите внимание, что в этом примере я добавил имя домена к моему имени пользователя, а не , добавив it.

Возможно, вместо того, чтобы пытаться подключиться к домену turboencabulator.net, я пытаюсь проверить пользователя как локальную (машинную) учетную запись, поставив перед моим именем пользователя .\ как:

enter image description here

Как Windows проверяет имя пользователя и пароль в локальной базе данных учетных записей?Использует ли он SSPI с пакетом Negotiate ?Если да, то какое значение он передает как pszTargetName?

Люди говорят о веб-серверах, http, сервере Team Foundation.Я действительно не знаю, откуда они это получают.Или они говорят о редактировании пользователя в активной директории, чтобы убедиться, что что-то присутствует - я не понимаю, почему мне нужно что-либо редактировать: Windows ничего не редактирует.

Что TargetName я использовал при вызове InitializeSecurityContext для проверки набора учетных данных?

Бонус Chatter

Вот глава из документации Application Verifier о том, почему они имеютпроверка, если кто-то по ошибке использует NTLM:

Почему необходим плагин NTLM

NTLM - это устаревший протокол аутентификации с недостатками, которые могут поставить под угрозу безопасность приложений и операционной системы.система.Наиболее важным недостатком является отсутствие проверки подлинности сервера, что может позволить злоумышленнику обманом заставить пользователей подключиться к поддельному серверу.Как следствие отсутствия аутентификации на сервере, приложения, использующие NTLM, также могут быть уязвимы к типу атаки, известной как атака «отражения».Последнее позволяет злоумышленнику перехватить сеанс аутентификации пользователя на легитимном сервере и использовать его для аутентификации злоумышленника на компьютере пользователя.Уязвимости NTLM и способы их использования являются целью увеличения исследовательской активности в сообществе безопасности.

Хотя Kerberos был доступен в течение многих лет, многие приложения до сих пор написаны для использования только NTLM.Это излишне снижает безопасность приложений.Однако Kerberos не может заменить NTLM во всех сценариях - главным образом в тех, где клиент должен пройти аутентификацию в системах, которые не присоединены к домену (домашняя сеть, возможно, является наиболее распространенной из них).Пакет безопасности Negotiate обеспечивает обратно-совместимый компромисс, который использует Kerberos всякий раз, когда это возможно, и возвращается к NTLM только тогда, когда нет другой возможности.Переключение кода для использования Negotiate вместо NTLM значительно повысит безопасность для наших клиентов, в то же время предоставляя лишь небольшое количество приложений или вообще не совместимыхностей,. Договариваться само собой не серебряная пуля - есть случаи, когда злоумышленник может принудительно перейти на NTLM, но это значительно сложнее в эксплуатации. Тем не менее, один немедленный улучшение заключается в том, что приложения, написанные для правильного использования, ведут переговоры автоматически защищены от атак отражения NTLM.

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

Как работает плагин

Штекер Verifier обнаруживает следующие ошибки:

  • Пакет NTLM указывается непосредственно в вызове AcquireCredentialsHandle (или API-оболочки более высокого уровня).

  • Целевое имя в вызове InitializeSecurityContext равно NULL.

  • Целевое имя в вызове InitializeSecurityContext не является правильно сформированным доменным именем в стиле SPN, UPN или NetBIOS.

Последние два случая заставят Negotiate вернуться к NTLM либо напрямую (первый случай), либо косвенно (контроллер домена вернет ошибку «принципал не найден» во втором случае, в результате чего Negotiate будет откатан).

Плагин также регистрирует предупреждения при обнаружении перехода на NTLM; например, когда SPN не найден контроллером домена. Они регистрируются только как предупреждения, поскольку они часто являются законными случаями, например, при аутентификации в системе, которая не присоединена к домену.

NTLM Остановки

5000 - Приложение явно выбрало пакет NTLM

Серьезность - Ошибка

Приложение или подсистема явно выбирают NTLM вместо Negotiate при вызове AcquireCredentialsHandle. Даже если клиент и сервер могут пройти аутентификацию с использованием Kerberos, это предотвращается явным выбором NTLM.

Как исправить эту ошибку

Исправление этой ошибки - вместо пакета NTLM выбрать пакет согласования. Как это сделать, будет зависеть от конкретной сетевой подсистемы, используемой клиентом или сервером. Некоторые примеры приведены ниже. Вам следует обратиться к документации по конкретной библиотеке или набору API, который вы используете.

APIs(parameter) Used by Application    Incorrect Value  Correct Value  
=====================================  ===============  ========================
AcquireCredentialsHandle (pszPackage)  “NTLM”           NEGOSSP_NAME “Negotiate”

Смотри также

Ответы [ 4 ]

9 голосов
/ 24 марта 2012

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

SSPI обычно используется для аутентификации пользователя по сети.Клиент вызывает AcquireCredentialsHandle для получения дескриптора учетных данных, а затем создает контекст безопасности, вызывая InitializeSecurityContext.Передайте буфер безопасности на сервер.Обратите внимание, что SSPI не определяет, как вы передаете буфер безопасности.Вы можете использовать http, tcp, named pipe, как вам нравится.После того, как сервер получит буфер безопасности.Точно так же он сначала вызывает AcquireCredentialsHandle.Затем он передает полученный буфер безопасности в AcceptSecurityContext и генерирует новый буфер безопасности.В некоторых случаях вновь сгенерированный буфер безопасности должен отправить обратно клиенту, и клиент передает его в InitializeSecurityContext и снова генерирует другой новый контекст безопасности.Этот процесс SSPI handshaking продолжается до тех пор, пока InitializeSecurityContext и AcceptSecurityContext оба не вернутся SEC_E_OK

Хотя SSPI был разработан для аутентификации по сети, многие приложения фактически выполняют петлевое подтверждение SSPI, котороеозначает, что и клиент, и сервер находятся в одном окне.Это действительно особый случай сетевой аутентификации.Конечным результатом петлевого квитирования SSPI является аутентифицированный контекст безопасности SSPI.С этим аутентифицированным SSPI приложение может выполнять QueryContextAttributes и ImpersonateSecurityContext.Поскольку вы, похоже, понятия не имеете, что означает targetName, я полагаю, что вы пытаетесь выполнить повторное рукопожатие.Хотя я могу ошибаться, но вы должны сказать нам, что вы пытаетесь сделать.

Чтобы понять, почему targetName необходим в Kerberos, но не в NTLM, вам нужно понять более основную реализацию.

Есть два разных способа получить дескриптор учетных данных.Обычно люди указывают использовать текущий контекст безопасности.(т.е. учетная запись, которую вы использовали для входа на свой компьютер).Вы также можете предоставить другой набор имени пользователя / пароля.Различные пакеты безопасности имеют разные значения на срок credentials.NTLM означает, что он собирается сохранить хэш вашего пароля.Kerberos означает, что он собирается сохранить билет, предоставляющий билет (TGT).Программисту SSPI вам не нужно беспокоиться об этом.

Теперь, когда клиент передает обработчик полученных учетных данных в InitializeSecurityContext, аналогично, другой пакет безопасности будет выполнять разные действия.NTLM собирается сгенерировать пакет NEGOTIATE при первом вызове InitializeSecurityContext.Никакие другие машины не участвуют в процессе генерации пакета NEGOTITATE.Пакет Kerberos сильно отличается.Он собирается поговорить с KDC, чтобы запросить билет на запрошенную услугу.Служба идентифицируется по имени участника службы (SPN) в Kerberos.Я не могу охватить все детали здесь.Чистая сеть заключается в том, что запрос на обслуживание для NTLM не предназначен, а запрос на обслуживание для Kerberos является целевым.Вы можете использовать один и тот же пакет NEGOTIATE NTLM для разных сервисов, используя метод аутентификации NTLM.Однако вам нужно использовать разные билеты службы Kerberos для разных служб, используя метод проверки подлинности Kerberos.Вот почему при вызове InitializeSecurityContext для Kerberos / Negotiate вам необходимо предоставить targetName.

Когда KDC получает запрос билета службы, он выполняет поиск в своей базе данных LDAP и выясняет, какая учетная записьсвязан с указанным servicePrincipalName.Учетная запись может быть учетной записью пользователя AD или учетной записью компьютера AD.KDC будет использовать главный ключ целевой учетной записи службы (генерируемый паролем учетной записи) для шифрования ключа сеанса.Этот зашифрованный сеансовый ключ будет передан от клиента серверу позже.

Теперь, помните, я сказал, что сервер также должен делать AcquireCredentialsHandle, и я сказал, что есть два основных подхода для обработки учетных данных?Я полагаю, вы используете первый подход для получения ручек учетных данных.Это означает, что он будет использовать текущий контекст безопасности.В случае обычной сетевой аутентификации это можно проиллюстрировать на следующем примере.Если ваш сервер является HTTP-сервером, это будет служебная учетная запись вашего IIS-сервера.Сервер IIS будет использовать свой главный ключ учетной записи службы для расшифровки зашифрованного ключа сеанса.Как только ключ сеанса получен, клиент и сервер продолжают обмен данными, используя ключ сеанса для выполнения шифрования и дешифрования.

Если это сценарий с обратной связью SSPI, это сложнее.Если вы работаете с domain\jane и выполняете зацикливание на себе.Вам необходимо указать имя участника-службы для домена \ jane.Что такое SPN для домена \ jane.Если вы проверяете объект пользователя AD, по умолчанию он отсутствует.Вам нужно исправить это вручную.

Есть одна вещь, которая у меня работала, но она без документов.В качестве имени участника-службы вы можете указать имя пользователя (например, jane@domain.com).Это работает для меня.Вы можете попробовать.

Если это не сработает, другой способ исправить это - использовать второй подход к серверной части AcquireCredentialsHandle.Вместо использования domain\jane дескриптора учетных данных вы указываете другую службу учетные данные учетной записи.Вы можете убедиться, что для учетной записи службы указан правильный SPN.Затем вы можете использовать SPN учетной записи службы в своем InitializeSecurityContext.Конечно, это также означает, что вам нужно жестко закодировать пароль своей учетной записи в коде.Необходимо соблюдать осторожность и убедиться, что вы полностью заблокировали эту учетную запись службы, чтобы, даже если пароль был украден, ваша среда AD не подвергалась большому риску.

2 голосов
/ 18 июля 2014

Я на пару лет опоздал на эту вечеринку ... Вчера я столкнулся с вашим вопросом, когда исследовал мою собственную проблему с SSPI.Сегодня утром, продолжая исследование, я наткнулся на статью, которая, кажется, предлагает решение вашего вопроса:

Статья Кейта Брауна, опубликованная в апреле 2001 года в MSDN Magazine, озаглавленная «Краткие сведения о безопасности: пересмотренный интерфейс поставщика поддержки безопасности», содержит примерКод, который раскрывает targetName (для проверки пароля), должен быть строкой в ​​форме «Машина \ Пользователь» или «Домен \ Пользователь».

Статья находится здесь: http://msdn.microsoft.com/en-us/magazine/cc301890.aspx

«Цифры», на которые ссылаются в статье (включая пример кода), находятся здесь: http://msdn.microsoft.com/en-us/magazine/bb985825.aspx

Я понимаю, что вы, вероятно, нашли решение этой проблемы давным-давно.Кроме того, я не могу подтвердить, что авторский код работает правильно на современных платформах Windows (я подозреваю, что это будет работать, но я не проверял поведение). Надеюсь, статья MSDN также будет полезным ресурсом для других.

1 голос
/ 20 марта 2012

Это немного зависит от SPN, против которого вы пытаетесь пройти аутентификацию. Мы выполняем проверку подлинности NTLM / SPNEGO на HTTP-серверах (только), и руководство предлагает , чтобы сервер HTTP / HTTPS регистрировал имя участника-службы как http/HOSTNAME. Поэтому, когда мы аутентифицируемся, мы просто добавляем http/ к имени хоста в верхнем регистре. Например, мы передаем:

http/TFS.DOMAIN.COM

в качестве цели InitializeSecurityContext, где TFS.DOMAIN.COM - это имя хоста в верхнем регистре, которое пользователь ввел для доступа к своему TFS-серверу.

Мы не пытаемся выполнять поиск DNS или сопоставление FQDN. Если пользователь просто набирает http://foo/, тогда наш SPN будет http/FOO. Это означает, что администратор сервера должен настроить http/FOO как SPN.

Не исключено, что администратор сервера настраивает машину, называет ее FOO и устанавливает SPN http/FOO, а затем выставляет эту машину в Интернете как extranet.domain.com. В этом случае они должны также настроить http/EXTRANET.DOMAIN.COM в качестве SPN. Это может быть сложно с балансировщиком нагрузки и т. Д., Но это должно быть обязанностью администратора сервера.

0 голосов
/ 21 марта 2018

Краткий ответ

TargetName - это имя пользователя, под которым код "server" будет работать как.

  • I 'm вошел как ian@stackoverflow.com
  • Я хочу подтвердить свою личность на steve@stackoverflow.com
  • Установить TargetName на steve@stackoverflow.com

Фон

Пакет аутентификации Negotiate попытается использовать Kerberos.Если он не может, он попытается вернуться к NTLM.

  • Вы хотите использовать Kerberos.
  • Вы не хотите использовать NTLM;он старый, устаревший, слабый, сломанный и не должен использоваться.
  • Для использования Kerberos вы должны предоставить TargetName
  • Без TargetName , Kerberos принципиально не может выполнить функцию

Вопрос возникает, если все стороны, участвующие во мне ( Ian ), проходят аутентификациюс Стивом , что TargetName я могу указать?

enter image description here

Здесь важно знать, что TargetName означает для Kerberos:

  • я хочу подтвердить свою личность steve@stackoverflow.local
  • контроллер домена передает мне зашифрованный BLOB-объект, который подтверждает мою личность
  • BLOB-объект зашифрован, поэтому steve@stackoverflow.local - единственный, кто может его расшифровать
  • контроллер домена знает, как его зашифровать для steve@stackoverflow.local, потому что я указал steve@stackoverflow.local в TargetName
  • Стив - это цель

Вот как Стив узнает, что BLOB-объект действителен.зашифрован, так что только он может расшифровать его.

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

Таким образом, в приведенном выше списке возможных имен работают три значения:

enter image description here

InitializeSecurityContext(credHandle, context, "steve@stackoverflow.local", ...);    
InitializeSecurityContext(credHandle, context, "stackoverflow.local\steve", ...);    
InitializeSecurityContext(credHandle, context, "steve", ...); //if we're in the same forest

Дополнительная путаница из-за гибкости (добро пожаловать в SPN)

SPNs Короткая версия

  • при использовании Kerberos вы должны указать имя пользователя в качестве TargetName
  • имя участника-службы "псевдоним" для имени пользователя
  • , поэтому вы можете указать имя участника-службы в качестве TargetName

SPNs Длинная версия

В приведенном выше случае я должен был знать, что код "server" будет работать как steve@stackoverflow.local.

Это боль.Я имею в виду, это нормально, когда я знаю, что это Стив.Но если я разговариваю с удаленной машиной, мне нужно узнать учетную запись пользователя , что код работает как?

  • я должен выяснить, что IIS работаеткак iisagent@stackoverflow.local?
  • я должен выяснить, что SQL Server работает как sqldaemon@stackoverflow.local?
  • и что, если служба работает на Local Service ;что пользователь домена вообще не является

К счастью (?) Kerberos создал псевдонимы (называемые Имена принципов обслуживания - или SPN):

  • если мне нужно пройти аутентификацию на веб-сервере http://bugtracker.stackoverflow.local
  • и служба IIS работает под учетной записью домена iisagent@stackoverflow.local
  • вместо того, чтобы указывать целевое имя iisagent@stackoverflow.local
  • я могу указать HTTP/bugtracker.stackoverflow.local
  • , потому что IIS зарегистрировал псевдоним с контроллером домена
  • HTTP/bugtracker.stackoverflow.local -> iisagent@stackoverflow.local

Все это требует, чтобы вы знали SPN, если хотите использовать его как TargetName .Различные стандартные продукты Microsoft регистрируют имена участников-служб при установке:

  • IIS : HTTP/[servername]
  • SQL Server : MSSQLSvc/[servername]:1433
  • SMTP : SMTPSVC/[servername]
  • Обмен файлами : HOST/[servername]

Все это недокументировано, и выад, если кто-то не настроен правильно.

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

Это примерно эквивалентно попытке указать "stackoverflow.com" вместо простого использования "35.186.238.101«.

...