簡體   English   中英

“檢測到 GSSException 缺陷令牌”- 嘗試使用 Kerberos 對運行在 Windows 上的 Tomcat 進行身份驗證時

[英]"GSSException Defective token detected" - when trying to Authenticate to Tomcat running on Windows using Kerberos

在 Windows 2012 上運行時,我正在努力驗證 Java web 容器(我已經嘗試過 Tomcat 和 Jetty)。

每次嘗試協商身份驗證方案時,我都會收到錯誤消息: 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

在 Active Directory 上創建 kerberos 主題用戶

重要提示:確保名字、姓氏和全名相同!

我的新用戶是:

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

登錄+域= kerberos500@nickis.life

NETBIOS\samAccountName = NICKIS\kerberos500

從 Windows Active Directory 服務器運行 setspn 命令

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

示例 output:

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

從 Windows Active Directory 服務器運行 ktpass 命令

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

示例 output:

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.

此時,您現在將擁有一個密鑰表文件:

c:\Users\Administrator\kerberos500.keytab

和一個用戶主體:

HTTP/kerberos500.nickis.life@NICKIS.LIFE

這些是需要提供給 GSSApi 以使用 Kerberos 進行單點登錄的 2 個輸入。

因此,我將這些輸入部署到我的 web 容器的 Hadoop 安全模塊中的 kerberos 安全 realm。

Curl 測試我嘗試使用curl 測試未成功:

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

Inte.net Explorer 測試我也試過使用 Inte.net Explorer。 我將nickis.life域添加到 Inte.net Explorer 中的受信任角色。 然后我在 inte.net 資源管理器中啟動站點: 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:?]

我很難過。 注意:我在這里和那里找到了幾個鏈接,但沒有一個鏈接像我在這里總結的那樣包含所有遵循的步驟,並且其中提供的解決方案都不適合我。

誰能追蹤我在這里搞砸了什么?

更新:

  • 我有域設置為fusionis.life的 AD 服務器,AD 服務器是WIN-OVV6VHBGIB8.fusionis.life
  • 我把tomcat服務器搬到了域里的另一台windows機器上。 DESKTOP-VTPBE99.fusionis.life
  • 我打開dnsmgmt.msc並添加了一個帶有“kerberos500.nickis.life”的“正向查找區域”,其中主機設置為DESKTOP-VTPBE99.fusionis.life框的 IP。
  • 我刪除了 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.lifenickis.life位於同一主機上

錯誤“ 檢測到有缺陷的令牌 ”可能意味着檢測到令牌。 如果失敗,這就是Negotiate機制在流行的Web瀏覽器中使用的內容 - 否則Web服務器沒有指示。 操作系統上,IE上的IE瀏覽器(以及Firefox,如果配置正確)基本上說,如果你不做Kerberos,我會發給你一個NTLM令牌。 服務器回復“沒辦法”我甚至不知道NTLM所以我打電話給你發送給我的有缺陷。 由於您似乎是第一次進行此設置,因此您可能沒有為Kerberos失敗時配置任何回退機制(例如NTLM),因此,該錯誤消息。 我們通過理解Kerberos失敗的原因來解決這個問題。 我想我在兩個地方看到了與SPN和可信站點相關的問題失敗的原因。 即使你解決了這兩個問題,還有第三個原因和第四個原因,它可能會繼續失敗,與加密有關。

  1. HTTP服務的與瀏覽器輸入的URL不匹配。 這些需要匹配,否則Kerberos將失敗。 要工作,瀏覽器應該使用: http//kerberos500.nickis.life8080 ,而不是http://nickis.life:8080 我根據你在創建語法中看到的內容說出來。 因為你已經對SPN進行了編碼:HTTP /kerberos500.nickis.life@NICKIS.LIFE。 這就是你需要使用http://kerberos500.nickis.life:8080的原因。 當您告訴它去http://nickis.life:8080時,瀏覽器將不知道如何訪問您的Web服務。 與上面的網址,瀏覽器假定它需要找到您的Active Directory運行Web服務 (任何與剛剛就任nickis.life就是在域控制器上運行)。 出於安全原因,DC不應運行Web服務器。
  2. 您需要在IE設置下將http://kerberos500.nickis.life添加為可信站點。 或者,* .nickis.life也可以。 (當它實際上稱為可信站點時,您將其稱為可信角色)。
  3. 您將Kerberos加密類型限制為DES-CBC-MD5。 從Windows Server 2008 Active Directory R2開始,默認情況下禁用DES。 如今,DES是一種過時且通常不安全的加密類型。 使用AES128甚至更好的AES256要好得多。 您可以通過下面的示例重新生成密鑰表來解決這個問題。
  4. 在AD用戶帳戶kerberos500中,轉到“帳戶”選項卡,滾動到底部,然后選中DES,AES 128和AES 256的所有框,然后確定您已離開對話框。 即使您在上面執行了所有操作,也必須選中這些框,否則Kerberos身份驗證仍會失敗。

如何正確地重新生成密鑰表:只要計划創建與該用戶帳戶關聯的密鑰表,就不應運行setspn -a命令將ADN添加到AD用戶。 原因是因為keytab creation命令將SPN作為命令的一部分添加到用戶帳戶。 如果按照上面的建議后你的方案不起作用,那么你需要通過setspn -D刪除SPN,如下所示:

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替換舊的keytab。 有關keytabs的更多深入信息,您可以在我的技術文章中閱讀更多有關如何在此處創建Kerberos keytabs的信息: Kerberos Keytabs - 解釋 我經常回過頭來根據我在這個論壇中看到的問題進行編輯。

順便說一句, HTTP / kerberos500.nickis.life是一個服務主體,而不是你在問題中寫的用戶主體。 我只使用Web瀏覽器在像這樣的HTTP場景中測試Kerberos,我不使用cURL。

如果你努力地完成我上面提到的所有四點,我會很肯定你會解決這個問題。

EDIT1:此答案假設您在具有完全限定域名kerberos500.nickis.life的主機上運行HTTP服務。 如果你沒有這樣名字的主持人,我的回答會略有變化。 如果有的話請告訴我。

編輯2:要使用http://nickis.life:8080的URL實現身份驗證的目標,您可以繼續使用您已創建的相同密鑰表。

在AD帳戶NICKIS \\ kerberos500上,轉到“帳戶”選項卡,滾動到底部,然后選中“為此帳戶使用Kerberos DES加密類型”復選框。

然后通過組策略在AD域級別啟用DES加密。 為此,請執行以下操作:

  1. 打開組策略管理控制台(GPMC)。
  2. 編輯默認域策略GPO。 (更安全地創建一個新的域級GPO並編輯它,但這取決於你)。
  3. 導航到計算機配置>策略> Windows設置>安全設置>本地策略>安全選項>“網絡安全:配置Kerberos允許的加密類型”,然后選中DES_CBC_MD5和DES_CBC_MD5的兩個復選框。 重要信息:在同一組策略中,還要確保還檢查RC4,AES128和AES256的復選框。 這些加密類型不會用於您網站的門票,但它們將用於域中的其他所有內容。 好了,你離開了對話框並關閉了GPMC。
  4. 在DC服務器和客戶端上運行'gpupdate / force'命令。
  5. 在客戶端上運行“klist purge”以清除所有Kerberos票證。
  6. 在Web瀏覽器中,清除緩存並刪除所有cookie。
  7. 確保DC服務器允許端口8080 TCP入站。
  8. 再試一遍。

參考: Kerberos支持的加密類型的Windows配置

編輯3:避免在同一台機器上運行Kerberos KDC(DC),客戶端和服務器。 這是獲得“瑕疵令牌錯誤”的經典方法,即使你已經做了其他正確的事情。

編輯4 :(最終更新由OP驗證):查看新的ktpass keytab創建輸出,我看到了這一點:目標域控制器:WIN-OVV6VHBGIB8.fusionis.life。 現在,keytab中定義的SPN是HTTP / kerberos500.nickis.life。 AD域名與您定義的SPN不同,因此除非您在這些域之間建立某種信任設置,否則這不會起作用。 如果您沒有信任,則需要使用HTTP / kerberos500.fusionis.life的SPN。

對我來說,問題是配置的 SPN 與指定的 url 不同。

所以假設 SPN 是HTTP/serviceX.domain.com ,訪問服務時,應該通過http://serviceX.doamin.com訪問,否則會拋出Defective token錯誤。

(我還發現所有與 Keberos 相關的錯誤消息都非常混亂,也許 MIT 故意讓它難以理解,相應地會更難破解。)

試試這個:

解決方案1

在Windows cmd上運行此命令:

ksetup / addkdc ksetup / addhosttorealmmap

並在瀏覽器上設置SPNEGO設置

解決方案2

嘗試使用Firefox,之前執行此操作:

1)在Firefox中打開此URL

about:config中

2)設置:network.negotiate-auth.trusted-uris

為需要協商身份驗證的任何群集DNS域設置(如啟用kerberos的群集HTTP身份驗證)。

例:

network.negotiate-auth.trusted-URI的= .lily.cloudera.com,.solr.cloudera.com

2)設置:network.auth.use-sspi = false 3)重啟Firefox 4)你必須從這里下載Windows isntaller:

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

5)將Kerberos客戶端配置復制到此處

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

6)使用MIT kerberos GUI客戶端創建票證

7)再次嘗試使用Firefox

希望它可以提供幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM