KrbException:指定的密钥版本不可用(44)

时间:2014-07-01 13:43:16

标签: java spring-security kerberos keytab

我使用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文件?

2 个答案:

答案 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