繁体   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