尝试在 Tomcat 7 (Windows Server 2012) 上实现集成的 Windows 身份验证,以便 Intranet 用户在访问我的 Web 应用程序时不需要输入他们的凭据。 以下 tomcat 手册:https://tomcat.apache.org/tomcat-7.0-doc/windows-auth-howto.html#Built-in_Tomcat_support
在运行 tomcat 的计算机上。 检查网络属性: 控制面板 -> 系统
完整的计算机名称:tomcatserver.global.lpl.top
域名:global.lpl.top
gpresult /R
组策略应用自:cdc.global.lpl.top
域名:全局
对这两个不同的“域”值有点困惑。是“global.lpl.top”还是“GLOBAL”?
有一个运行 Tomcat 的技术用户:tomcatuser,密码为 tomcatuserpassword。
我要求系统管理员调用两条命令:
setspn -A HTTP/tomcatserver.global.lpl.top tomcatuser
ktpass /out c:\tomcat.keytab /mapuser tomcatuser@GLOBAL /princ HTTP/tomcatserver.global.lpl.top@GLOBAL /pass tomcatuserpassword /kvno 0
现在我有了 tomcat.keytab 文件。
让我们验证一下。
1.
PS > setspn -l tomcatuser Registered ServicePrincipalNames for CN=tomcatuser,OU=Services,OU=Accounts,OU=...,OU=Delegated,DC=global,DC=lpl,DC=top: HTTP/tomcatserver.global.lpl.top
这似乎是对的。
2.
jdk1.7.0_79\bin>klist -kt C:\tomcat.keytab
Key tab: C:\tomcat.keytab, 1 entry found.
[1] Service principal: HTTP/tomcatserver.global.lpl.top@GLOBAL KVNO: 0
似乎是对的。
3。 创建 krb5.ini 文件:
[libdefaults]
default_realm = GLOBAL
default_keytab_name = FILE:C:\tomcat.keytab
default_tkt_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
default_tgs_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
forwardable=true
[realms]
GLOBAL = {
kdc = cdc.global.lpl.top:88
}
[domain_realm]
global= GLOBAL
.global= GLOBAL
global.lpl.top= GLOBAL
.global.lpl.top= GLOBAL
“kdc = cdc.global.lpl.top:88”中的“:88”是从哪里来的?我应该把它留在那里吗?
根据 http://www.itadmintools.com/2011/07/creating-kerberos-keytab-files.html将 krb5.ini 文件放到 c:\Windows\krb5.ini 并使用 kinit:
jdk1.7.0_79\bin\kinit HTTP/tomcatserver.global.lpl.top@GLOBAL
Password for HTTP/tomcatserver.global.lpl.top@GLOBAL: tomcatserpassword Exception: krb_error 6 Client not found in Kerberos database (6) Client not foun d in Kerberos database KrbException: Client not found in Kerberos database (6) at sun.security.krb5.KrbAsRep.(KrbAsRep.java:76) at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:319) at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:364) at sun.security.krb5.internal.tools.Kinit.(Kinit.java:221) at sun.security.krb5.internal.tools.Kinit.main(Kinit.java:113) Caused by: KrbException: Identifier doesn't match expected value (906) at sun.security.krb5.internal.KDCRep.init(KDCRep.java:143) at sun.security.krb5.internal.ASRep.init(ASRep.java:65) at sun.security.krb5.internal.ASRep.(ASRep.java:60) at sun.security.krb5.KrbAsRep.(KrbAsRep.java:60) ... 4 more
现在有些事情很糟糕。 并尝试使用 key 表文件:
jdk1.7.0_79\bin>kinit -k -t C:\tomcat.keytab HTTP/tomcatserver.global.lpl.top@GLOBAL Exception: krb_error 6 Client not found in Kerberos database (6) Client not foun d in Kerberos database KrbException: Client not found in Kerberos database (6) at sun.security.krb5.KrbAsRep.(KrbAsRep.java:76) at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:319) at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:364) at sun.security.krb5.internal.tools.Kinit.(Kinit.java:221) at sun.security.krb5.internal.tools.Kinit.main(Kinit.java:113) Caused by: KrbException: Identifier doesn't match expected value (906) at sun.security.krb5.internal.KDCRep.init(KDCRep.java:143) at sun.security.krb5.internal.ASRep.init(ASRep.java:65) at sun.security.krb5.internal.ASRep.(ASRep.java:60) at sun.security.krb5.KrbAsRep.(KrbAsRep.java:60) ... 4 more
感觉也不对。
还尝试使用 SPNEGO 过滤器在 tomcat 上运行测试应用程序,并在日志中得到以下异常:
SEVERE: Exception starting filter SpnegoHttpFilter javax.servlet.ServletException: javax.security.auth.login.LoginException: Client not found in Kerberos database (6) Caused by: KrbException: Identifier doesn't match expected value (906)
我不介意看看它比较了哪些标识符 - 有什么办法吗?
是的,stackoverflow 上有很多同类问题,但大多数都没有得到解答。我读了很多,但在我的配置中仍然看不到错误。 将不胜感激任何帮助。 谢谢。
编辑: 我向 tomcat 添加了 Kerberos 调试选项:
2017-08-03 12:51:33 Commons Daemon procrun stdout initialized
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true
ticketCache is null isInitiator true KeyTab is ///C:/tomcat7/conf/tomcat.keytab
refreshKrb5Config is false principal is HTTP/tomcatserver.global.lpl.top@GLOBAL
tryFirstPass is false useFirstPass is false storePass is false clearPass is false
>>> KeyTabInputStream, readName(): GLOBAL
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): tomcatserver.global.lpl.top
>>> KeyTab: load() entry length: 72; type: 23
Java config name: C:\tomcat7\conf\krb5.conf
Loaded from Java config
Added key: 23version: 0
Ordering keys wrt default_tkt_enctypes list
default etypes for default_tkt_enctypes: 23 17.
>>> KdcAccessibility: reset
Added key: 23version: 0
Ordering keys wrt default_tkt_enctypes list
default etypes for default_tkt_enctypes: 23 17.
default etypes for default_tkt_enctypes: 23 17.
>>> KrbAsReq creating message
>>> KrbKdcReq send: kdc=cdc.global.lpl.top UDP:88, timeout=30000, number of retries =3, #bytes=150
>>> KDCCommunication: kdc=cdc.global.lpl.top UDP:88, timeout=30000,Attempt =1, #bytes=150
>>> KrbKdcReq send: #bytes read=84
>>> KdcAccessibility: remove cdc.global.lpl.top:88
>>> KDCRep: init() encoding tag is 126 req type is 11
>>>KRBError:
sTime is Thu Aug 03 12:51:40 MSK 2017 1501753900000
suSec is 36472
error code is 6
error Message is Client not found in Kerberos database
realm is GLOBAL
sname is krbtgt/GLOBAL
msgType is 30
[Krb5LoginModule] authentication failed
Client not found in Kerberos database (6)
编辑 2: 我要求系统管理员检查AD中的tomcatuser,它的登录名仍然是“tomcatuser”。不应该改成“HTTP/tomcatserver.global.lpl.top@GLOBAL”吗?
最佳答案
在您的问题中,您问了三个问题。我将解决每一个问题并解释如何解决这个问题。它看起来很简单。
- “对这两个不同的“域”值有点困惑。它是“global.lpl.top”还是“GLOBAL”?
答:是global.lpl.top。这是正确编写的完全限定的 DNS 域名,指的是您的 Active Directory 域,这也是它的 DNS 域名,也是大写时的 Kerberos 域名(我稍后会讲到) . Kerberos 需要 DNS 才能正常运行,这意味着您不能在配置文件或 key 表中仅将 AD 域名称为“GLOBAL”。如前所述,您的 Kerberos 领域应该正确地写为 GLOBAL.LPL.TOP,这应该被编码到您的 key 表中(我将在第 3 点中讨论)。您在整个过程中使用了缩写名称“GLOBAL”,我强烈怀疑这就是 Kerberos SSO 无法正常工作的原因。
- ““kdc = cdc.global.lpl.top:88”中的“:88”是从哪里来的?我应该把它留在那里吗?”
回答:你可以把它留在那里。请注意,即使您删除它,它实际上仍然可以工作,因为 Kerberos 始终假定端口 88 是标准端口。但请注意:此文件中的实际问题是它需要反射(reflect)完全限定名称 GLOBAL.LPL.TOP - 而不是我们在第 1 点中谈到的缩写名称。
- “我不介意看看它比较了哪些标识符——有什么办法吗?”
答案:好吧,这将归结为实际解决问题。为此,在修复 krb5.ini 后,您需要使用正确的完全限定 Kerberos 域名(即 GLOBAL.LPL.TOP)重新生成 key 表。在此之前,从 tomcatuser AD 帐户中删除 SPN。所以这两个单独的命令看起来像这样并按以下顺序运行它们:
先运行这个:
setspn -D HTTP/tomcatserver.global.lpl.top tomcatuser
然后运行它。
ktpass /out c:\tomcat.keytab /mapuser tomcatuser@GLOBAL.LPL.TOP /princ
HTTP/tomcatserver.global.lpl.top@GLOBAL.LPL.TOP /pass
tomcatuserpassword /kvno 0
注意:有关如何正确创建 Kerberos key 表的更多信息,请参阅我的文章。看起来您缺少一些与加密相关的附加参数,ptype 和/kvno 开关不是必需的,如果您使用它可能会导致问题。可以肯定的是,如果我是你,我会这样运行它:
ktpass -out c:\tomcat.keytab /mapUser tomcatuser@GLOBAL.LPL.TOP +rndPass /mapOp set +DumpSalt /crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL /princ HTTP/tomcatserver.global.lpl.top@GLOBAL.LPL.TOP
编辑:(针对我刚刚注意到的您的编辑做出的回应)
“编辑2:我要求系统管理员检查AD中的tomcatuser,它的登录名仍然是“tomcatuser”。难道不应该改为“HTTP/tomcatserver.global.lpl.top@GLOBAL”吗?”
回答:否 - 因为 keytab 生成命令会执行此操作。让 key 表生成命令执行此操作,而不是您的系统管理员。
关于Tomcat集成Windows认证: Client not found in Kerberos database,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45472685/