我使用Spring安全性对SPNEGO实施了kerberos身份验证。 我的电脑上一切正常。
我使用了确切的keytab文件和krb5配置,这些配置在我的计算机上工作并将其放入测试环境中。 这两个环境都使用tomcat 6,我已经安装了精确的jdk版本。
但是,在测试环境中,我得到以下内容:
16:27:33 WARN http-8180-1 org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter - Negotiate Header was invalid: Negotiate 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
org.springframework.security.authentication.BadCredentialsException: Kerberos validation not succesfull
at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:69)
at org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider.authenticate(KerberosServiceAuthenticationProvider.java:86)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter.doFilter(SpnegoAuthenticationProcessingFilter.java:131)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:877)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:594)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Specified version of key is not available (44))
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.java:67)
... 22 more
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Specified version of key is not available (44))
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:788)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:875)
at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:548)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:146)
at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136)
... 25 more
Caused by: KrbException: Specified version of key is not available (44)
at sun.security.krb5.EncryptionKey.findKey(EncryptionKey.java:588)
at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:270)
at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:144)
at sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:108)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:771)
... 33 more
我已根据测试计算机上的this post测试了我的keytab文件,一切看起来都不错。
我的机器 - Windows 7专业版 测试机 - Windows Server 2008 R2
keytab在一台机器上有效而在另一台机器上无效的任何明显原因?
我的下一步是重新生成密钥表,但这只是伏都教,而且我不喜欢伏都教。
谢谢, 利奥尔
修改
我没有直接使用KRB5ModuleLogin。我使用kerberos extension的弹簧安全性。
在幕后显然使用该模块,但我不知道如何配置它(可能通过krb5.conf文件)。
这是我的相关弹簧配置:
<bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<property name="ticketValidator">
<bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<property name="servicePrincipal" value="${krb.service.prinicipal}" />
<!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
<!-- See the Javadoc for more information on that -->
<property name="keyTabLocation" value="${krb.keytab.location}" />
<property name="debug" value="${krb.debug}" />
</bean>
</property>
<property name="userDetailsService" ref="LDAPUserDetailsService" />
</bean>
<!-- This bean definition enables a very detailed Kerberos logging -->
<bean
class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<property name="debug" value="${krb.debug}" />
<property name="krbConfLocation" value="${krb.conf.location}"/>
</bean>
注入GlobalSunJaasKerberosConfig的krb5.conf如下:
[libdefaults]
default_realm = DOMAIN.COM
forwardable = true
proxiable = true
[realms]
DOMAIN.COM = {
kdc = controller1.domain.com
kdc = controller2.domain.com
kdc = controller3.domain.com
admin_server = controler.domain.com
default_domain = DOMAIN.COM
}
[domain_realm]
.domain.com = DOMAIN.COM
domain.com = DOMAIN.COM
[login]
krb4_convert = true
krb4_get_tickets = false
编辑2
我已经调试到测试服务器,并与我的计算机进行了比较。
这是我的开发中的登录上下文的调试信息(有效):
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is file:/C:/Eclipse/Loans_maven/http-web.keytab refreshKrb5Config is false principal is HTTP/testing.domain.com@DOMAIN.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
>>> KeyTabInputStream, readName(): DOMAIN.COM
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): testing.domain.com
>>> KeyTab: load() entry length: 71; type: 23
Added key: 23version: 24
Ordering keys wrt default_tkt_enctypes list
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 3 1 23 16 17 18.
principal's key obtained from the keytab
principal is HTTP/testing.domain.com@DOMAIN.COM
EncryptionKey: keyType=23 keyBytes (hex dump)=0000: 05 DF 2F D1 10 9E 3D 3B 60 F1 10 96 5F 6A F1 28 ../...=;`..._j.(
Added server's keyKerberos Principal HTTP/testing.domain.com@DOMAIN.COMKey Version 24key EncryptionKey: keyType=23 keyBytes (hex dump)=
0000: 05 DF 2F D1 10 9E 3D 3B 60 F1 10 96 5F 6A F1 28 ../...=;`..._j.(
[Krb5LoginModule] added Krb5Principal HTTP/testing.domain.com@DOMAIN.COM to Subject
Commit Succeeded
这是在测试服务器中完成登录时的调试信息:
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is file:/D:/Apps/fibi-loans/config/http-web.keytab refreshKrb5Config is false principal is HTTP/testing.domain.com@DOMAIN.COM tryFirstPass is false useFirstPass is false storePass is false clearPass is false
>>> KeyTabInputStream, readName(): DOMAIN.COM
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): testing.domain.com
>>> KeyTab: load() entry length: 71; type: 23
Added key: 23version: 24
Ordering keys wrt default_tkt_enctypes list
Using builtin default etypes for default_tkt_enctypes
default etypes for default_tkt_enctypes: 3 1 23 16 17.
principal's key obtained from the keytab
principal is HTTP/testing.domain.com@DOMAIN.COM
EncryptionKey: keyType=23 keyBytes (hex dump)=0000: 05 DF 2F D1 10 9E 3D 3B 60 F1 10 96 5F 6A F1 28 ../...=;`..._j.(
Added server's keyKerberos Principal HTTP/testing.domain.com@DOMAIN.COMKey Version 24key EncryptionKey: keyType=23 keyBytes (hex dump)=
0000: 05 DF 2F D1 10 9E 3D 3B 60 F1 10 96 5F 6A F1 28 ../...=;`..._j.(
[Krb5LoginModule] added Krb5Principal HTTP/testing.domain.com@DOMAIN.COM to Subject
Commit Succeeded
正如您所看到的,它完全相同(除了keytab文件的位置,但正如我所说,keytab文件是相同的) 另一个区别是dev支持enc_type 18,而测试没有,但这似乎无关紧要,因为密钥类型是23(RC4-HMAC-NT),并且两者都支持。
那么为什么,为了好的缘故,测试机器在用户尝试登录时拒绝keytab文件?
答案 0 :(得分:1)
Java检查keytab文件的version-nummer(kvno)是否与kerberos数据库(LDAP服务器)中的版本号相同。如果两个数字都不同,则会出现此错误。
您可以通过使用jdk工具ktab.exe
及其参数-n 0
创建密钥表来绕过此检查。 Java不会使用knvo = 0
检查密钥表。
然而,最好不要使用ktab.exe
,而是在ADS服务器上生成带有ktpass.exe
的密钥表,该密钥表直接在文件中写入正确的版本号。
请参阅此文章:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6984764
答案 1 :(得分:0)
您的密钥表可能已过期。从机器机密中提取密钥表DB不是一个好主意,因为Windows会在一定时间后重置密码。所以你的问题可能是客户端为更新版本的机器秘密生成了一张票,但你有一张旧票。检查计算机帐户AD中的pwdLastSet
字段
最好配置登录条目以访问计算机帐户的票证缓存。像这样:
tomcat-accept {
com.sun.security.auth.module.Krb5LoginModule required doNotPrompt=true
useTicketCache=true isInitiator=false refreshKrb5Config=true;
};
请记住设置this。