"Обнаружен дефектный токен GSSException" - при попытке аутентификации в Tomcat, работающем в Windows, с помощью Kerberos

я изо всех сил пытаюсь аутентифицироваться в веб-контейнере Java (я пробовал как Tomcat, так и Jetty) при работе в Windows 2012.

каждый раз, когда я пытаюсь согласовать схему auth, я получаю ошибку:org.ietf.jgss.GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)

воспроизведение

начните с настройки экземпляра Windows Server 2012 или 2016 и установки доменных служб active directory.

в моем примере, я создано:

  • домен NETBIOS: NICKIS

  • домен Dns: nickis.жизни

создайте пользователя субъекта kerberos в Active Directory

ВАЖНО: УБЕДИТЕСЬ, ЧТО ИМЯ, ФАМИЛИЯ И ПОЛНОЕ ИМЯ СОВПАДАЮТ!

новый пользователь в моем случае:

DN = CN=kerberos500,CN=Users,DC=nickis,DC=life

логин+домен = kerberos500@nickis.life

NETBIOSsamAccountName = NICKISkerberos500

выполните команду setspn с сервера Windows Active Directory

setspn -A HTTP/nickis.life@NICKIS.LIFE kerberos500

пример:

C:UsersAdministrator>setspn -A HTTP/nickis.life kerberos500
Checking domain DC=nickis,DC=life 
Registering ServicePrincipalNames for CN=kerberos500,CN=Users,DC=nickis,DC=life
        HTTP/kerberos500.nickis.life
Updated object

выполните команду ktpass с сервера Windows Active Directory

ktpass -out c:UsersAdministratorkerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass XXXXpasswordforkerberos500userXXXX -crypto DES-CBC-MD5 -pType KRB5_NT_PRINCIPAL +DesOnly

пример:

C:UsersAdministrator>ktpass -out c:UsersAdministratorkerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass xxxxxxxx -crypto DES-CBC-MD5 -pType KRB5_NT_PRINCIPAL +DesOnly
Targeting domain controller: WIN-OVV6VHBGIB8.nickis.life
Using legacy password setting method
Successfully mapped HTTP/kerberos500.nickis.life to kerberos500.
Key created.
Output keytab to c:UsersAdministratorkerberos500.keytab:
Keytab version: 0x502
keysize 71 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x3 (DES-CBC-MD5) keylength 8 (0xcd07200bea625d20)
Account kerberos500 has been set for DES-only encryption.

на этом этапе у вас теперь будет keytab файл:

c:UsersAdministratorkerberos500.keytab

и принципал пользователя:

HTTP/kerberos500.nickis.life@NICKIS.LIFE

это 2 входа, которые необходимы для предоставления GSSApi для получения единого входа с Kerberos.

поэтому я развернул эти входы в область безопасности kerberos моего веб-контейнера в модуле безопасности Hadoop.

тест Curl я безуспешно пытался использовать curl, чтобы проверить это:

curl --negotiate -u : http://nickis.life:8080/my/webapp

тест Internet Explorer I также попробовал использовать Internet Explorer. Я добавил nickis.life домен для доверенных ролей в Internet Explorer. Затем я запускаю сайт в internet explorer:http://nickis.жизнь:8080

в любом случае, я получаю ошибку ниже:

org.apache.hadoop.security.authentication.client.AuthenticationException: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
    at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.authenticate(KerberosAuthenticationHandler.java:398) ~[hadoop-auth-2.7.1.jar:?]

...

Caused by: org.ietf.jgss.GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
    at sun.security.jgss.GSSHeader.<init>(Unknown Source) ~[?:1.8.0_131]
    at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) ~[?:1.8.0_131]
    at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) ~[?:1.8.0_131]
    at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.run(KerberosAuthenticationHandler.java:365) ~[hadoop-auth-2.7.1.jar:?]
    at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.run(KerberosAuthenticationHandler.java:347) ~[hadoop-auth-2.7.1.jar:?]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_131]
    at javax.security.auth.Subject.doAs(Unknown Source) ~[?:1.8.0_131]
    at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.authenticate(KerberosAuthenticationHandler.java:347) ~[hadoop-auth-2.7.1.jar:?]

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

может ли кто-нибудь проследить, что я здесь напортачил?

обновление:

  • у меня есть сервер AD с доменом fusionis.life, а сервер объявлений -WIN-OVV6VHBGIB8.fusionis.life
  • я переместил сервер tomcat на другая машина windows в домене. DESKTOP-VTPBE99.fusionis.life
  • открыл dnsmgmt.msc и добавлена " зона прямого просмотра "с" kerberos500.nickis.жизнь " с хостом, установленным на IP

2 ответов


ошибка "обнаружен дефектный токен", вероятно, означает, что протокол NTLM маркер был обнаружен. Это то, что механизм переговоров использует внутри популярных веб-браузеров, если kerberos fails-когда не проинструктировано веб-сервером в противном случае.  On windows операционные системы, веб-браузер IE на нем (и Firefox, если настроен правильно) в основном говорит, Если вы не будете делать Kerberos, я собираюсь отправить вам токен NTLM.  И сервер отвечает " Нет "я даже не знаю NTLM, поэтому я называю то, что вы мне прислали, дефектным.  Поскольку вы, похоже, настраиваете это в первый раз, вы, вероятно, не настроили какой-либо резервный механизм (например, NTLM) для сбоя Kerberos, поэтому это сообщение об ошибке. Мы решаем это, понимая, почему Kerberos терпит неудачу.  Я думаю, что вижу причину неудачи в вашем вопросе в двух местах, связанных с SPNs и доверенными сайтами. Даже если вы разрешите эти два элемента, есть третья причина и четвертая причина почему он может продолжать терпеть неудачу, связанные с шифрованием.

  1. на spn для службы HTTP не соответствует URL, введенному браузером. Они должны совпадать, иначе Kerberos завершится ошибкой. Для работы браузер должен использовать: http://kerberos500.nickis.жизнь:8080, а не http://nickis.жизнь:8080. Я говорю это, основываясь на том, что я видел в своем keytab синтаксис создания. В этом вы закодировали SPN как таковой: Протокол HTTP/kerberos500.nickis.жизнь@NICKIS.ЖИЗНЬ. Вот почему вам нужно использовать http://kerberos500.nickis.жизнь:8080. Браузер не будет знать, как добраться до вашего веб-сервиса, когда вы скажете ему перейти к http://nickis.жизнь:8080. С этим верхним URL-адресом браузер предполагает, что ему нужно найти веб-службу, работающую на вашем Active Directorydomaincontroller (ничего с nickis.предполагается, что жизнь выполняется на контроллере домена). DCs никогда не должен запускать веб-серверы для соображения безопасности.
  2. вам нужно добавить http://kerberos500.nickis.жизни как доверенный сайт в настройках IE. Альтернативно.* ,nickis.жизнь тоже будет работать. (Вы назвали его доверенными ролями, когда он на самом деле называется доверенными сайтами).
  3. вы ограничиваете тип шифрования Kerberos DES-CBC-MD5. Начиная с Windows Server 2008 Active Directory R2, DES по умолчанию отключен. DES является устаревшим и вообще небезопасным типом шифрования дни. Гораздо лучше использовать AES128 или даже лучше, AES256. Вы можете исправить это, повторно создав keytab в моем примере ниже.
  4. в учетной записи пользователя ad kerberos500 перейдите на вкладку Учетная запись, прокрутите вниз и установите все флажки для DES, AES 128 и AES 256, и OK вы выходите из диалоговых окон. Вы должны установить эти флажки, даже если вы сделали все правильно выше, иначе проверка подлинности Kerberos все равно завершится ошибкой.

Как правильно повторно произвести keytab: не следует запускать команду setspn-a для добавления SPN пользователю AD всякий раз, когда вы планируете сделать keytab, связанный с этой учетной записью пользователя.  Причина в том, что команда создания keytab добавляет SPN в учетную запись пользователя как часть команды.  Если ваш сценарий не работает после моего совета выше, то вам нужно будет удалить SPN через setspn-D, как показано ниже:

setspn -D HTTP/nickis.life@NICKIS.LIFE kerberos500

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

ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass XXXXpasswordforkerberos500userXXXX -crypto ALL -pType KRB5_NT_PRINCIPAL


затем замените старую keytab на новую. Для получения дополнительной подробной информации о keytabs, вы можете прочитать больше из моей технической статьи о том, как создать Kerberos keytabs здесь:Протокол Kerberos Keytab-Файлов – Пояснил. Я часто возвращаюсь и редактирую его на основе вопросов, которые я вижу здесь, на этом форуме.

кстати, HTTP / kerberos500.nickis.жизни является участником службы, а не пользователем, как вы написали в своем вопросе. Я использую только веб-браузеры для тестирования Kerberos в сценариях HTTP, подобных этому, я не использую cURL.

Я уверен, что если вы старательно пройдете все четыре пункта, которые я выделил выше, вы решите эту проблему.

EDIT1: этот ответ предполагает, что у вас есть служба HTTP, работающая на хосте с полным доменным именем kerberos500.nickis.жизнь. Если у вас нет такого хоста с таким именем, мой ответ немного изменится. Пожалуйста, дайте мне знать, если есть.

EDIT2: для достижения цели аутентификации с помощью URL http://nickis.жизнь:8080, то вы можете продолжать использовать ту же keytab вы уже создали.

на рекламном аккаунте NICKIS\kerberos500 перейдите на вкладку аккаунт, прокрутите вниз и установите флажок " Использовать шифрование Kerberos DES типы для данного аккаунта".

затем включите само шифрование DES на уровне домена AD с помощью групповой политики. Для этого проведите следующее:

  1. Откройте консоль управления групповой политикой (GPMC).
  2. изменить GPO политики домена по умолчанию. (Безопаснее создать новый GPO на уровне домена и отредактировать его, но это зависит от вас).
  3. перейдите к конфигурации компьютера > политики > Параметры Windows > Параметры безопасности > Локальные политики > Параметры безопасности > "сетевая безопасность: настройка типов шифрования, разрешенных для Kerberos" и установите оба флажка для DES_CBC_MD5 и DES_CBC_MD5. Важно: в той же групповой политике также убедитесь, что флажки для RC4, AES128 и AES256 также проверены. Эти типы шифрования не будут использоваться для билетов на ваш веб-сайт, но они будут использоваться для всего остального в домене. и хорошо, вы выходите из диалоговых окон и закрываете GPMC.
  4. выполните команду " gpupdate / force как на сервере DC, так и на клиенте.
  5. запустите 'klist purge' на клиенте, Чтобы очистить все билеты Kerberos.
  6. в веб-браузере очистите кэш и удалите все файлы cookie.
  7. убедитесь,что сервер DC разрешает входящий порт 8080 TCP.
  8. попробуй еще раз.

ссылки: конфигурации Windows для Kerberos поддерживается тип шифрования

EDIT 3: избегайте запуска Kerberos KDC (DC), клиента и сервер на то же самое машины. Это классический рецепт получения "дефектной ошибки токена", даже если вы все сделали правильно.

EDIT 4: (окончательное обновление, которое было проверено OP): посмотрел на новый вывод создания ktpass keytab, и я увидел это: таргетинг контроллера домена: WIN-OVV6VHBGIB8.фузионис.жизнь. Теперь определенным SPN на вкладке keytab является HTTP / kerberos500.nickis.жизнь. Имя домена AD отличается от определенного вами SPN, поэтому это не происходит работать, если у вас нет какой-то настройки доверия между этими доменами. Если у вас нет доверия, вам нужно использовать SPN HTTP/kerberos500.фузионис.вместо жизни.


попробуйте это:

Решение 1

запустите это в Windows cmd:

ksetup / addkdc ksetup / addhosttorealmmap

и установить настройки SPNEGO в браузере

решение 2

попробуйте с Firefox, сделайте это перед:

1) Откройте этот URL в Firefox

about: config

2) Установите это: сеть.переговоры-авт.доверенный-uris

установить для любого кластера DNS домен, требующий согласованной проверки подлинности (например, включена проверка подлинности http кластера kerberos).

пример:

network.negotiate-auth.trusted-uris=.lily.cloudera.com.solr.cloudera.com

2) Установите это: сеть.автор.использовать-sspi=false 3) Перезапустить Firefox 4) Вы должны скачать Windows isntaller здесь:

http://web.mit.edu/kerberos/dist/#kfw-4.0

5) скопируйте конфигурацию клиента Kerberos в вот!--1-->

C:\ProgramData\MIT\Kerberos5\krb5.ini

6) Создайте билет с клиентом GUI MIT kerberos

7) повторите попытку с Firefox

надеюсь, что это может помочь.