【问题标题】:"GSSException Defective token detected" - when trying to Authenticate to Tomcat running on Windows using Kerberos“检测到 GSSException 有缺陷的令牌” - 尝试使用 Kerberos 对在 Windows 上运行的 Tomcat 进行身份验证时
【发布时间】:2018-04-23 22:45:15
【问题描述】:

在 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 实例并安装 Active Directory 域服务。

在我的示例中,我创建了:

  • 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

示例输出:

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

示例输出:

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

这些是提供给 GSSApi 以使用 Kerberos 进行单点登录所需的 2 个输入。

因此,我将这些输入部署到了 Hadoop 安全模块中的 Web 容器的 kerberos 安全领域。

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:?]

我被难住了。注意:我在这里和那里找到了几个链接,但是它们都没有像我在这里总结的那样包含所遵循的步骤,并且其中提供的解决方案都没有为我工作。

谁能追踪我在这里搞砸了什么?

更新:

  • 我有域设置为fusionis.life的AD服务器,AD服务器是WIN-OVV6VHBGIB8.fusionis.life
  • 我将 tomcat 服务器移动到域中的另一台 Windows 机器上。 DESKTOP-VTPBE99.fusionis.life
  • 我打开了dnsmgmt.msc 并添加了一个带有“kerberos500.nickis.life”的“Forward Lookup Zone”,并将A HOST 设置为DESKTOP-VTPBE99.fusionis.life 框的IP。
  • 我删除了 AD 帐户,重新创建了它,然后按照票证上的一个答案中的建议再次重新生成了 keytab。

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 更新文件保存在服务器上,然后将 Service Principal 更新为 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 位于同一主机上

【问题讨论】:

  • 这是一个非常广泛的问题。为了更好地回答它,我建议向它添加 kerberos 和 spnego 标签。也许也可以提供赏金。只是我的 .02。
  • @JohnRSmith 好的。
  • 有人提到可能是区分大小写导致我的问题
  • 我怀疑它是否区分大小写。其中很多内容不区分大小写,例如 Web 浏览器 URL。此处可能存在一些影响该方案的 Active Directory 含义。
  • 抱歉,我遇到了 Windows + VirtualBox 的问题,它杀死了 VM,我不得不对此进行测试。我正在尝试解决。

标签: java windows active-directory kerberos gssapi


【解决方案1】:

错误“检测到有缺陷的令牌”可能意味着检测到 令牌。如果 失败,这就是 Negotiate 机制在流行的网络浏览器中使用的方法——否则网络服务器没有指示。在 操作系统上,它上面的 IE 网络浏览器(以及 Firefox,如果配置正确的话)基本上会说,如果你不使用 Kerberos,我将向你发送一个 NTLM 令牌。服务器回答“不可能”我什至不知道 NTLM,所以我称你发送给我的东西有缺陷。由于您似乎是第一次进行此设置,因此您可能没有为 Kerberos 失败时配置任何回退机制(例如 NTLM),因此,该错误消息。我们通过了解 Kerberos 失败的原因来解决这个问题。我想我在与 SPN 和受信任的站点有关的两个地方看到了您的问题失败的原因。即使你解决了这两个问题,还有第三个和第四个原因会导致它继续失败,这与加密有关。

  1. HTTP 服务的 与浏览器输入的 URL 不匹配。这些需要匹配,否则 Kerberos 将失败。要工作,浏览器应该使用:http://kerberos500.nickis.life:8080,而不是http://nickis.life:8080。我这么说是基于我在您的 创建语法中看到的。您已经将 SPN 编码为:HTTP/kerberos500.nickis.life@NICKIS.LIFE。这就是您需要使用http://kerberos500.nickis.life:8080 的原因。当您告诉浏览器转到http://nickis.life:8080 时,浏览器将不知道如何访问您的 Web 服务。使用该顶级 URL,浏览器假定它需要找到在您的 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 命令将 SPN 添加到 AD 用户。原因是因为 keytab 创建命令将 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。有关 keytab 的更多深入信息,您可以在我的技术文章中阅读更多关于如何创建 Kerberos keytab 的信息:Kerberos Keytabs – Explained。我经常根据在此论坛中看到的问题返回并对其进行编辑。

顺便说一句,HTTP/kerberos500.nickis.life 是服务主体,而不是您在问题中所写的用户主体。我只使用网络浏览器在像这样的 HTTP 场景中测试 Kerberos,我不使用 cURL。

我很肯定,如果你认真完成我上面强调的所有四点,你就会解决这个问题。

EDIT1: 此答案假定您在具有完全限定域名 kerberos500.nickis.life 的主机上运行 HTTP 服务。如果您没有同名的主机,我的回答会略有变化。如果有请告诉我。

EDIT2:要达到使用http://nickis.life:8080 URL 进行身份验证的目的,您可以继续使用您已经创建的相同keytab。

在 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. 在网络浏览器中,清除缓存并删除所有 cookie。
  7. 确保 DC 服务器允许端口 8080 TCP 入站。
  8. 再试一次。

参考:Windows Configurations for Kerberos Supported Encryption Type

编辑 3:避免在 same 机器上运行 Kerberos KDC(DC)、客户端和服务器。即使您做对了所有其他事情,这也是获得“有缺陷的令牌错误”的经典方法。

编辑 4:(由 OP 验证的最终更新):查看了新的 ktpass 密钥表创建输出,我看到了:目标域控制器:WIN-OVV6VHBGIB8.fusionis.life。现在,keytab 中定义的 SPN 是 HTTP/kerberos500.nickis.life。 AD 域名与您定义的 SPN 不同,因此除非您在这些域之间设置了某种信任,否则这将不起作用。如果您没有信任,则需要使用 HTTP/kerberos500.fusionis.life 的 SPN。

【讨论】:

  • 此答案假定您在具有完全限定域名 kerberos500.nickis.life 的主机上运行 HTTP 服务。如果您没有同名的主机,我的回答会略有变化。如果有请告诉我。
  • 重要提示:在同一个组策略中,请确保 RC4、AES128 和 AES256 的复选框也被选中!这些加密类型不会用于您网站的票证,但会用于域中的所有其他内容。
  • 明白。这是您正在测试的复杂场景,使用自 Windows Server 2008 R2 版本以来在 Active Directory 中默认禁用的加密协议 (DES)。当前标准是使用 AES256 的 Windows Server 2016。我已经尽我所能提供了这个答案,我认为我无法涵盖您在测试所有这些内容时可能遇到的所有可能的细微差别。
  • 我已经给你提供了如何解决这个问题的框架。你只需要坚持下去,你就会解决它。在 DC 上完成测试后,您必须恢复到我的原始答案才能让 Kerberos SSO 到 AD 在单独的主机上工作。
  • 我添加了一个“EDIT3”来结束它。它基本上说要避免在同一台机器上运行 Kerberos KDC(DC)、客户端和服务器,即使您已正确完成其他所有操作,这也是获取“缺陷令牌”错误的经典方法。
【解决方案2】:

试试这个:

解决方案 1

在 windows cmd 上运行:

ksetup /addkdc ksetup /addhosttorealmmap

并在浏览器上设置 SPNEGO 设置

解决方案 2

尝试使用 Firefox,在此之前这样做:

1) 在 Firefox 中打开此 URL

关于:配置

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) 重启火狐 4) 你必须从这里下载 Windows 安装程序:

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

5) 将 Kerberos 客户端配置复制到此处

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

6) 使用 MIT kerberos GUI 客户端创建票证

7) 使用 Firefox 重试

希望对你有帮助。

【讨论】:

  • OP 的 SPN 与在 Web 浏览器中输入的内容不匹配,因此 Kerberos 将永远无法工作,除非他首先修复该问题。再加上至少一个其他问题,如果不是我上面概述的一两个问题。 :-)
  • ksetup /addkdc ksetup /addhosttorealmmap 抱怨/AddHostToRealmMap requires 2 options (only 0 supplied).
猜你喜欢
  • 1970-01-01
  • 2014-07-19
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
相关资源
最近更新 更多