我使用GSS-API创建了2个演示Kerberos客户端。 一个在Python3中,第二个在Java中。 两个客户似乎都大致相同,并且两者都在工作"因为我获得了我的Java GSS-API服务主体接受的服务票证。
然而,在测试中,我注意到Python客户端将服务票据保存在kerberos凭证缓存中,而Java客户端似乎没有保存票证。
我使用" klist"查看凭据缓存的内容。
我的客户使用FreeIPA作为Kerberos环境在Lubuntu 17.04虚拟机上运行。我正在使用OpenJDK 8 u131。
问题1: Java GSS-API是否不保存凭证缓存的服务票证?或者我可以更改我的代码吗?
问题2:服务票据未保存到缓存这一事实是否有任何缺点?
我的假设是缓存的服务票证减少了与KDC的交互,但How to save Kerberos Service Ticket using a Windows Java client?上的评论表明情况并非如此,但this Microsoft technote表示"客户端不需要返回每次想要访问这个特定的服务器时都要到KDC上。
问题3:来自python客户端的缓存服务票证在几分钟后消失 - 在到期日之前很久。是什么导致他们消失?
Python代码
#!/usr/bin/python3.5
import gssapi
from io import BytesIO
server_name = 'HTTP/app-srv.acme.com@ACME.COM'
service_name = gssapi.Name(server_name)
client_ctx = gssapi.SecurityContext(name=service_name, usage='initiate')
initial_client_token = client_ctx.step()
Java代码
System.setProperty("java.security.krb5.conf","/etc/krb5.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
GSSManager manager = GSSManager.getInstance();
GSSName clientName;
GSSContext context = null;
//try catch removed for brevity
GSSName serverName =
manager.createName("HTTP/app-srv.acme.com@ACME.COM", null);
Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
//use default credentials
context = manager.createContext(serverName,
krb5Oid,
null,
GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(false);
context.requestConf(false);
context.requestInteg(true);
byte[] token = new byte[0];
token = context.initSecContext(token, 0, token.length);
修改
虽然最初的问题集中在使用Java GSS-API构建Java Kerberos客户端,但GSS不是必须的。我对其他适用于Java的Kerberos方法持开放态度。现在我正在试验Apache Kerby curb-client。
到目前为止,Java GSS-API似乎有两个问题:
1)它使用凭证缓存来获取TGT(确定),但不使用缓存服务票证(不是)。
2)它无法访问KEYRING类型的凭证缓存。 (通过行为确认,调试Java运行时安全类以及该代码中的注释。对于Lubuntu / FreeIPA组合,我使用KEYRING是开箱即用的默认设置。这不适用于Windows,并且可能不适用于其他Linux Kerberos组合。