"GSSException Обнаружен дефектный токен" - при попытке аутентификации на Tomcat, работающем в Windows с использованием Kerberos
Я изо всех сил пытаюсь пройти аутентификацию в веб-контейнере Java (я пробовал и Tomcat, и Jetty) при работе в Windows 2012.
Каждый раз, когда я пытаюсь использовать схему аутентификации Negotiate, я получаю сообщение об ошибке: org.ietf.jgss.GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
Действия по воспроизведению
Начните с настройки экземпляра Windows Server 2012 или 2016 и установите службы домена активного каталога.
В моем примере я создал:
Домен NETBIOS : NICKIS
DNS-домен: nickis.life
Создайте тему субъекта kerberos в Active Directory
ВАЖНО: УБЕДИТЕСЬ, ЧТО ИМЯ ИМЯ, ИМЯ И ПОЛНОЕ ИМЯ!
Новый пользователь в моем случае:
DN = CN=kerberos500,CN=Users,DC=nickis,DC=life
логин + домен = kerberos500@nickis.life
NETBIOS \ samAccountName = NICKIS\kerberos500
Запустите команду setspn с сервера Windows Active Directory
setspn -A HTTP/nickis.life@NICKIS.LIFE kerberos500
Пример вывода:
C:\Users\Administrator>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:\Users\Administrator\kerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass XXXXpasswordforkerberos500userXXXX -crypto DES-CBC-MD5 -pType KRB5_NT_PRINCIPAL +DesOnly
Пример вывода:
C:\Users\Administrator>ktpass -out c:\Users\Administrator\kerberos500.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:\Users\Administrator\kerberos500.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:\Users\Administrator\kerberos500.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 Я также пытался использовать Internet Explorer. я добавил nickis.life
домен для доверенных ролей в Internet Explorer. Затем я запускаю сайт в Internet Explorer: http://nickis.life: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$2.run(KerberosAuthenticationHandler.java:365) ~[hadoop-auth-2.7.1.jar:?]
at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler$2.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:?]
Я в тупике. ПРИМЕЧАНИЕ: я нашел несколько ссылок здесь и там, но ни одна из них не была полностью включена в шаги, которые я выполнил, как я подытожил здесь, и ни одно из решений, предоставленных внутри, не помогло мне.
- Я пытаюсь войти в систему Kerberos с другого компьютера в домене, на котором работает сервер
- Я пробовал все виды комбинаций вариантов генерации клавиш, ни одна из которых не работала.
- Там нет дубликата SPN.
- Я попытался настроить DNS на сервере домена как
A
запись. - Интересно, может быть, есть какие-то шаги по настройке сервера Kerberos для Windows, и сотрудник Microsoft проверил, что это не должно быть здесь: https://social.msdn.microsoft.com/Forums/sharepoint/en-US/db15ad96-e269-436e-952f-fe9dfb39da8a/setting-up-a-test-windows-server-active-directory-for-kerberos-testing?forum=winserverDS
Кто-нибудь может отследить, что я здесь напортачу?
ОБНОВИТЬ:
- У меня AD сервер с доменом
fusionis.life
и сервер ADWIN-OVV6VHBGIB8.fusionis.life
- Я переместил сервер Tomcat на другую машину Windows в домене.
DESKTOP-VTPBE99.fusionis.life
- я открыл
dnsmgmt.msc
и добавил "Зону прямого просмотра" с "kerberos500.nickis.life" с HOST, установленным на IP-адресDESKTOP-VTPBE99.fusionis.life
коробка. - Я удалил учетную запись AD, заново создал ее, а затем заново сгенерировал таблицу ключей, как это было предложено в одном из ответов в билете.
C:\Users\Administrator>ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/kerberos500.nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass xxxxxxxxx -crypto ALL -pType KRB5_NT_PRINCIPAL
Targeting domain controller: WIN-OVV6VHBGIB8.fusionis.life
Using legacy password setting method
Successfully mapped HTTP/kerberos500.nickis.life to kerberos500.
Key created.
Key created.
Key created.
Key created.
Key created.
Output keytab to c:\Users\Administrator\kerberos500.keytab:
Keytab version: 0x502
keysize 67 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x1 (DES-CBC-CRC) keylength 8 (0x04e30b9183ba8389)
keysize 67 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x3 (DES-CBC-MD5) keylength 8 (0x04e30b9183ba8389)
keysize 75 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x17 (RC4-HMAC) keylength 16 (0xe39a141de38abd8750bf9c0bf49fd1c5)
keysize 91 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x12 (AES256-SHA1) keylength 32 (0xe368a1b060cfe4816f522c1c5f62ca07fe201ed96c6d018054dfbd5b86251892)
keysize 75 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x11 (AES128-SHA1) keylength 16 (0x1b1a548fa2893a78c6f4c7f9c482b614)
Я сохранил обновленный файл keytab на сервере, а затем обновил субъект обслуживания до
HTTP/kerberos500.nickis.life@NICKIS.LIFE
Я вошел на компьютер tomcat как пользователь домена, добавил http://kerberos500.nickis.life/ на доверенные сайты, а затем перешел на http://kerberos500.nickis.life:8764/
Я проверил все комбинации флажков шифрования на вкладке "учетная запись" kerberos500 AD.
Теперь я получаю новую ошибку...
GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos credentails)
ОБНОВИТЬ:
Решено наконец. Я получил эту последнюю ошибку, потому что мне нужно fusionis.life
быть на том же хосте, что и nickis.life
3 ответа
Ошибка "Обнаружен дефектный токен", вероятно, означает, что был обнаружен токен ntlm. Это то, что механизм согласования использует в популярных веб-браузерах, если происходит сбой Kerberos - если веб-сервер не дает указаний об этом. В операционных системах Windows веб-браузер IE (и Firefox, если он настроен правильно) в основном говорит: если вы не будете выполнять Kerberos, я отправлю вам маркер NTLM. И сервер отвечает "ни за что". Я даже не знаю NTLM, поэтому я звоню тому, что вы мне прислали. Поскольку вы, кажется, настраиваете это впервые, вы, вероятно, не настраивали какой-либо резервный механизм (например, NTLM) для сбоя Kerberos, поэтому это сообщение об ошибке. Мы решаем это, понимая, почему Kerberos терпит неудачу. Я думаю, что вижу причину сбоя в вашем вопросе, в двух местах, связанных с именами SPN и доверенными сайтами. Даже если вы разрешите эти два элемента, существует третья и четвертая причина, по которой он может продолжать сбой, связанный с шифрованием.
- Значение spn для службы HTTP не соответствует URL-адресу, введенному браузером. Они должны совпадать, иначе Kerberos потерпит неудачу. Для работы браузер должен использовать: http://kerberos500.nickis.life:8080/, а не http://nickis.life:8080/. Я говорю это на основе того, что я видел в вашем синтаксисе создания keytab. Вы запрограммировали имя участника-службы следующим образом: HTTP/kerberos500.nickis.life@NICKIS.LIFE. Вот почему вам нужно использовать http://kerberos500.nickis.life:8080/. Браузер не будет знать, как получить доступ к вашему веб-сервису, когда вы скажете ему перейти на http://nickis.life:8080/. С этим верхним URL-адресом браузер предполагает, что ему нужно найти веб-службу, работающую на контроллере домена Active Directory ( предполагается, что все, что содержит только nickis.life, запускается на контроллере домена). DC не должны запускать веб-серверы по соображениям безопасности.
- Вам необходимо добавить http://kerberos500.nickis.life/ в качестве доверенного сайта в настройках IE. В качестве альтернативы, *.nickis.life также будет работать. (Вы называли это доверенными ролями, когда это на самом деле называется доверенными сайтами).
- Вы ограничиваете тип шифрования Kerberos до DES-CBC-MD5. Начиная с Windows Server 2008 Active Directory R2, DES по умолчанию отключен. В наши дни DES является устаревшим и обычно небезопасным типом шифрования. Намного лучше использовать AES128 или даже лучше, AES256. Вы можете исправить это, заново сгенерировав keytab в моем примере ниже.
- В учетной записи пользователя AD kerberos500, перейдите на вкладку Учетная запись, прокрутите вниз и установите все флажки для DES, AES 128 и AES 256, и ОК, вы выходите из диалоговых окон. Вы должны поставить эти флажки, даже если вы все сделали правильно, иначе аутентификация Kerberos все равно не будет выполнена.
Как правильно заново сгенерировать таблицу ключей: Вам не следует запускать команду setspn -a для добавления имени участника-службы к пользователю AD всякий раз, когда вы планируете создать таблицу ключей, связанную с этой учетной записью пользователя. Причина в том, что команда создания keytab добавляет имя участника-службы к учетной записи пользователя как часть команды. Если ваш сценарий не работает после того, как вы следовали моему совету выше, вам нужно удалить 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
Затем замените старую таблицу ключей новой. Для получения дополнительной подробной информации о клавиатурных ярлыках вы можете прочитать больше в моей технической статье о том, как создавать ключевые таблицы Kerberos, здесь: Kerberos Keytabs - Explained. Я часто возвращаюсь и редактирую его, основываясь на вопросах, которые я вижу здесь на этом форуме.
Кстати, HTTP / kerberos500.nickis.life является принципалом службы, а не пользователем, как вы написали в своем вопросе. Я использую только веб-браузеры для тестирования Kerberos в сценариях HTTP, подобных этому, я не использую cURL.
Я уверен, что если вы усердно пройдете все четыре пункта, которые я выделил выше, вы решите эту проблему.
EDIT1: в этом ответе предполагается, что на хосте запущена служба HTTP с полностью определенным доменным именем kerberos500.nickis.life. Если у вас нет такого хоста с таким именем, мой ответ немного изменится. Пожалуйста, дайте мне знать, если таковые имеются.
РЕДАКТИРОВАТЬ 2: Для достижения цели аутентификации с использованием URL-адреса http://nickis.life:8080/, вы можете продолжать использовать ту же самую таблицу ключей, которую вы уже создали.
В учетной записи AD NICKIS\kerberos500 перейдите на вкладку Учетная запись, прокрутите вниз и установите флажок "Использовать типы шифрования Kerberos DES для этой учетной записи".
Затем включите шифрование DES на уровне домена AD с помощью групповой политики. Для этого проведите следующее:
- Откройте консоль управления групповой политикой (GPMC).
- Изменить стандартную политику домена GPO. (Вместо этого безопаснее создать новый объект групповой политики на уровне домена и отредактировать его, но это зависит от вас).
- Перейдите к Конфигурации компьютера> Политики> Параметры Windows> Параметры безопасности> Локальные политики> Параметры безопасности> "Сетевая безопасность: настройка типов шифрования, разрешенных для Kerberos" и установите оба флажка для DES_CBC_MD5 и DES_CBC_MD5. ВАЖНО: В той же групповой политике также убедитесь, что флажки для RC4, AES128 и AES256 также отмечены. Эти типы шифрования не будут использоваться для билетов на ваш веб-сайт, но они будут использоваться для всего остального в домене. и ОК, вы выходите из диалоговых окон и закрываете консоль управления групповыми политиками.
- Выполните команду "gpupdate /force" как на сервере DC, так и на клиенте.
- Запустите на клиенте команду "klist purge", чтобы очистить все билеты Kerberos.
- В веб-браузере очистите кеш и удалите все куки.
- Убедитесь, что на сервере DC разрешен входящий порт 8080 TCP.
- Попробуйте снова.
Ссылка: Конфигурации Windows для Kerberos Поддерживаемый тип шифрования
РЕДАКТИРОВАТЬ 3: Избегайте запуска Kerberos KDC (DC), клиент и сервер на одном компьютере. Это классический рецепт для получения "Дефектной ошибки токена", даже если вы все сделали правильно.
РЕДАКТИРОВАТЬ 4: (Окончательное обновление, которое было проверено OP): Посмотрел новый вывод создания таблицы ключей ktpass, и я увидел это: Контроллер домена таргетинга: WIN-OVV6VHBGIB8.fusionis.life. Теперь определенное имя участника-службы в таблице ключей - HTTP/kerberos500.nickis.life. Имя домена AD отличается от имени SPN, которое вы определили, поэтому оно не будет работать, если вы не настроите доверительные отношения между этими доменами. Если у вас нет доверия, вам нужно вместо этого использовать имя участника-службы HTTP/kerberos500.fusionis.life.
для меня проблема в том, что настроенный SPN отличается от указанного URL-адреса.
Итак, скажем, SPNHTTP/serviceX.domain.com
, при доступе к сервису он должен быть доступен черезhttp://serviceX.doamin.com
, иначе он выброситDefective token
ошибка.
(Я также нашел все сообщения об ошибках, связанные с Keberos, довольно запутанными, возможно, MIT намеренно затруднил их понимание, соответственно, их было бы еще труднее взломать.)
Попробуй это:
Решение 1
запустите это на windows cmd:
ksetup / addkdc ksetup / addhosttorealmmap
и установите настройки SPNEGO в браузере
Решение 2
попробуйте с Firefox, сделайте это раньше:
1) открыть этот URL в Firefox
о: конфигурации
2) Установите это: network.negotiate-auth.trusted-uris
Установите для любого кластерного DNS-домена, требующего согласованной аутентификации (например, кластерная аутентификация с поддержкой Kerberos HTTP).
Пример:
network.negotiate-auth.trusted-URIs =.lily.cloudera.com,.solr.cloudera.com
2) Установите это: network.auth.use-sspi = false 3) Перезапустите Firefox 4) Вы должны скачать Windows isntaller отсюда:
http://web.mit.edu/kerberos/dist/
5) Скопируйте конфигурацию клиента Kerberos сюда
C: \ ProgramData \ MIT \ Kerberos5 \ krb5.ini
6) Создайте заявку с помощью клиента MIT kerberos GUI
7) Попробуйте снова с Firefox
Надеюсь, это поможет.