我正在使用基于Windows域登录的SSO进行Web应用,为此我选择验证Kerberos票证.但是现在我遇到了一个我无法找到解决方案的问题.我设法验证一个没有例外的票证,但当我试图获取userName时,NullPointerException
抛出,因为用户名是null
,我不知道哪里有问题.
如果在验证期间没有出现任何异常,为什么用户名为null?
我如何获得userName:
String clientName = gssContext.getSrcName().toString();
我基于此创建了我的客户端:
使用GSSManager验证Kerberos票证
如何通过GSS-API获取kerberos服务票?
http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/single-signon.html
更新1:
我如何设置内容,只需复制粘贴表格/sf/ask/17360801/:
final Oid spnegoOid = new Oid("1.3.6.1.5.5.2"); GSSManager gssmgr = GSSManager.getInstance(); // tell the GSSManager the Kerberos name of the service GSSName serviceName = gssmgr.createName(this.servicePrincipal, GSSName.NT_USER_NAME); // get the service's credentials. note that this run() method was called by Subject.doAs(), // so the service's credentials (Service Principal Name and password) are already // available in the Subject GSSCredential serviceCredentials = gssmgr.createCredential(serviceName, GSSCredential.INDEFINITE_LIFETIME, spnegoOid, GSSCredential.ACCEPT_ONLY); // create a security context for decrypting the service ticket GSSContext gssContext = gssmgr.createContext(serviceCredentials); // decrypt the service ticket System.out.println("Entering accpetSecContext..."); System.out.println( new String (Base64.encodeBase64( gssContext.acceptSecContext(this.kerberosTicket, 0, this.kerberosTicket.length) ) )); // get the client name from the decrypted service ticket // note that Active Directory created the service ticket, so we can trust it String clientName = gssContext.getSrcName().toString();
更新2:
如果我根据此https://spring.io/blog/2009/09/28/spring-security-kerberos-spnego-extension设置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 )在javax.security.auth.Subject.doAs的java.security.AccessController.doPrivileged(Native Method)中(Subject.java:422)
private static class KerberosValidateAction implements PrivilegedExceptionAction{ byte[] kerberosTicket; public KerberosValidateAction(byte[] kerberosTicket) { this.kerberosTicket = kerberosTicket; } @Override public String run() throws Exception { GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null); context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length); String user = context.getSrcName().toString(); // ERROR! context.dispose(); return user; } }
更新3:
还尝试将Java版本从1.8更改为1.7,如此处所建议的,使用Kerberos进行域身份验证失败.没有结果.
更新4:
首先.不要使用Java 1.8 b40和b45,它们都被破坏了.并且不要在本地PC上测试它,它不起作用(我不知道为什么).
更改了最新的(b65)Java版本后,我得到了关于encription的异常(无法找到适当类型的密钥来解密AP REP - AES256 ......).我已经通过Java Cryptography Extension(JCE)修复了Java 1.8并重新创建了keytab,/crypto AES256-SHA1
毕竟我得到了异常:
GSSException:在sun.security的sun.security.jgss.GSSContextImpl.acceptSecContext(未知来源)sun.security.jgss.krb5.Krb5Context.acceptSecContext(未知来源)的GSS-API级别(机制级别:校验和失败)未指定失败GssServer上的.jgss.GSSContextImpl.acceptSecContext(未知来源)$ GssServerAction.run(GssServer.java:159)... 4更多引起:KrbException:在sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt上校验和失败(来自sun.security.krb5.KrbApReq.authenticate(未知来源)的sun.security.krb5.EncryptedData.decrypt(未知来源)sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(未知来源)的未知来源sun.security.krb5.KrbApReq.(未知来源),位于sun.security.jgss.krb5.InitSecContextToken.(未知来源)... 8更多引起:java.security.GeneralSecurityException:校验和在sun.security.krb5失败. sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(Unk)中的internal.crypto.dk.ArcFourCrypto.decrypt(未知来源)nown来源)......还有14个
我尝试了本教程和其他方法来创建keytabfile,但我仍然没有解决方案.