Java 带有空SrcName的GSSContext
我正在使用基于Windows域登录的SSO的web应用程序,为此,我选择验证Kerberos票证。但现在我面临着一个无法解决的问题。我设法在没有异常的情况下验证票证,但当我试图获取用户名时,会抛出Java 带有空SrcName的GSSContext,java,kerberos,spring-security-kerberos,jgss,Java,Kerberos,Spring Security Kerberos,Jgss,我正在使用基于Windows域登录的SSO的web应用程序,为此,我选择验证Kerberos票证。但现在我面临着一个无法解决的问题。我设法在没有异常的情况下验证票证,但当我试图获取用户名时,会抛出NullPointerException,因为用户名是null,我不知道问题出在哪里 如果在验证过程中没有任何异常,为什么用户名为空? 如何获取用户名: String clientName=gssContext.getSrcName().toString() 我基于以下内容创建我的客户机: 更新1
NullPointerException
,因为用户名是null
,我不知道问题出在哪里
如果在验证过程中没有任何异常,为什么用户名为空?
如何获取用户名:
String clientName=gssContext.getSrcName().toString()代码>
我基于以下内容创建我的客户机:
更新1:
如何设置内容,只需在此处复制粘贴表单:
更新2:
如果我基于此设置spring security,也会出现相同的错误:
位于的java.lang.NullPointerException
org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136)
在
org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:125)
位于java.security.AccessController.doPrivileged(本机方法)
javax.security.auth.Subject.doAs(Subject.java:422)
私有静态类KerberosValidateAction实现PrivilegedExceptionAction{
字节[]kerberosTicket;
公共KerberosValidateAction(字节[]kerberosTicket){
this.kerberosTicket=kerberosTicket;
}
@凌驾
公共字符串run()引发异常{
GSSContext context=GSSManager.getInstance().createContext((GSSCredential)null);
acceptSecContext(kerberosTicket,0,kerberosTicket.length);
字符串user=context.getSrcName().toString();//错误!
context.dispose();
返回用户;
}
}
更新3:
还尝试将Java版本从1.8更改为1.7,如这里所建议的。没有结果
更新4:
首先。不要使用Java1.8B40和b45,它们都已损坏。不要在本地PC上测试它,它不工作(我不知道为什么)
在最新的(b65)Java版本上更改后,我遇到了关于加密的异常(找不到合适类型的密钥来解密AP REP-AES256…)。我已经通过Java 1.8的Java加密扩展(JCE)修复了这个问题,并使用/crypto AES256-SHA1
重新创建了keytab。在所有这些之后,我得到了异常:
GSS异常:GSS-API级别未指定故障(机制级别:
校验和失败)在
sun.security.jgss.krb5.Krb5Context.acceptSecContext(未知源)位于
sun.security.jgss.GSSContextImpl.acceptSecContext(未知源)位于
sun.security.jgss.GSSContextImpl.acceptSecContext(未知源)位于
GssServer$GssServerAction.run(GssServer.java:159)
... 4更多
原因:KrbeException:在时校验和失败
sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(未知)
来源)在
sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(未知)
源)位于sun.security.krb5.EncryptedData.decrypt(未知源)位于
sun.security.krb5.KrbApReq.authenticate(未知源)位于
sun.security.krb5.KrbApReq.(未知源)位于
sun.security.jgss.krb5.InitSecContextToken。(未知源)
... 8个以上
原因:java.security.GeneralSecurityException:校验和
失败于
sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(未知
来源)在
sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(未知源)
... 14多
我尝试了其他方法来创建keytab文件,但仍然没有解决方案。当您尝试获取SrcName时,上下文似乎没有完全建立。这似乎是ScrName为空的原因。根据,acceptSecContext()生成一个令牌,如果该令牌不为null,则应将该令牌发送给对等方。
调用acceptSecContext()后,应检查isEstablished()是否返回false。如果是这样的话
如果此方法返回false,则表示需要从其对等方获得令牌以继续上下文建立阶段。true的返回值表示已建立上下文的本地端。这可能仍然需要向对等方发送令牌(如果由GSS-API生成)。在上下文建立阶段,可以调用isProtReady()方法来确定上下文是否可用于每消息操作。这允许应用程序在未完全建立的上下文上使用每消息操作
本教程将详细介绍这一点:
acceptSecContext方法可以依次返回一个令牌。如果确实如此,则接受方应将该令牌发送给发起方,然后发起方应再次调用initSecContext并将该令牌传递给它。每次initSecContext或acceptSecContext返回令牌时,调用该方法的应用程序都应将令牌发送给其对等方,该对等方应将令牌传递给其相应的方法(acceptSecContext或initSecContext)。这将一直持续到完全建立上下文(当上下文的isEstablished方法返回true时就是这种情况)
在实现我的GSSAPI套接字演示时,我遇到了相同的校验和失败
错误,这是对Oracle GSSAPI代码的修改。
我在注册到FreeIPA kerberos领域的Linux机器上执行代码。
我使用了Linux系统的vanillakrb5.conf
文件。票证etype
没有限制:
...
[libdefaults]
default_realm = AUTHDEMO.IT
dns_lookup_realm = true
dns_lookup_kdc = true
rdns = false
ticket_lifetime = 24h
forwardable = true
udp_preference_limit = 0
...
FreeIPA领域默认使用类型18票据(AES-256)
关于我的应用程序,它配置了以下策略文件:
grant CodeBase "file:./app.jar" {
permission java.security.AllPermission;
};
grant CodeBase "file:./app.jar"
Principal javax.security.auth.kerberos.KerberosPrincipal
"servicename@AUTHDEMO.IT" {
permission java.net.SocketPermission "*", "accept";
permission javax.security.auth.kerberos.ServicePermission
"servicename@AUTHDEMO.IT", "accept";
};
在执行应用程序时,我在接受者端遇到以下错误:
GSS异常:GSS-API级别未指定故障(机制级别:
不支持带有HMAC SHA1-96的加密类型AES256CTS模式
支持/启用)...
[libdefaults]
default_realm = AUTHDEMO.IT
dns_lookup_realm = true
dns_lookup_kdc = true
rdns = false
ticket_lifetime = 24h
forwardable = true
udp_preference_limit = 0
...
grant CodeBase "file:./app.jar" {
permission java.security.AllPermission;
};
grant CodeBase "file:./app.jar"
Principal javax.security.auth.kerberos.KerberosPrincipal
"servicename@AUTHDEMO.IT" {
permission java.net.SocketPermission "*", "accept";
permission javax.security.auth.kerberos.ServicePermission
"servicename@AUTHDEMO.IT", "accept";
};
DemoServer {
com.sun.security.auth.module.Krb5LoginModule required
principal="servicename@AUTHDEMO.IT"
storeKey=true
debug=true; #not mandatory
};