我正在尝试使用Java 8中引入的S4U2Proxy。不幸的是,我没有成功找到那么多的例子。我的要求是客户会发送证书。然后,我应该委托(使用kerberos)他的请求,连接到KDC,获取TGT,获取服务票证代表用户联系另一台服务器,然后通过提供服务票证最终联系实际服务。如果java 8没有提供干净的方法,你能不能指向我可能解决我的需求的其他工具。
Subject.doAs(subject, new PrivilegedAction<Object>() {
@Override
public Object run() {
GSSManager manager = GSSManager.getInstance();
GSSCredential self = null;
try {
GSSName selfUser = manager.createName("serviceWhoWantstoImpersonate", GSSName.NT_USER_NAME);
Oid krb5Oid = new Oid( "1.2.840.113554.1.2.2");
self = manager.createCredential(selfUser.canonicalize(krb5Oid), GSSCredential.DEFAULT_LIFETIME, krb5Oid, GSSCredential.INITIATE_ONLY);
GSSName user = manager.createName(clientName, GSSName.NT_USER_NAME);
GSSCredential impCred = ((ExtendedGSSCredential) self).impersonate(user);
} catch (GSSException e) {
e.printStackTrace();
}
return null;
}
});
显然会有关于如何在KDC中设置SPN的问题?该服务帐户是否获得授权?是否已将正确的SPN分配给该服务帐户?当用户“猴子”否认所有类型的授权?等等。现在我觉得我在KDC中做了正确的设置。我的问题是上面甚至在它击中KDC之前就已经发生了。任何有效的输入都会有所帮助。
编辑: 经过一些研究后,我能够使用java 8执行S4u2self和s4u2proxy。感到至少有一个例子应该由Oracle文档提供。无论如何,我现在正在进入下一阶段。 现在我需要处理的另一个场景是跨域kerberos证书委派。从我到目前为止看到的java 8文档,它推断出目前不支持跨领域。它仍然是真的吗?
答案 0 :(得分:2)
我已经为Java 8中的Kerberos SFU扩展功能构建了一个完整的独立演示应用程序:https://github.com/ymartin59/java-kerberos-sfudemo
以下是允许为模拟用户生成带有TGS票证的SPNEGO令牌的短代码段:
GSSManager manager = GSSManager.getInstance();
GSSName userName = manager.createName("targetUser", GSSName.NT_USER_NAME);
GSSCredential impersonatedUserCreds =
((ExtendedGSSCredential)serviceCredentials).impersonate(userName);
final Oid KRB5_PRINCIPAL_OID = new Oid("1.2.840.113554.1.2.2.1");
GSSName servicePrincipal =
manager.createName("HTTP/webservice-host.domain.ltd", KRB5_PRINCIPAL_OID);
ExtendedGSSContext extendedContext =
(ExtendedGSSContext) manager.createContext(servicePrincipal,
new Oid("1.3.6.1.5.5.2"),
impersonatedUserCreds,
GSSContext.DEFAULT_LIFETIME);
final byte[] token = extendedContext.initSecContext(new byte[0], 0, 0);
当心extendedContext
尚未建立。可能需要多轮服务器。
Java 8 Kerberos code尚不支持跨领域模拟:请参阅JDK-8005819
Java服务帐户可以托管在一个领域中,只要此领域明确附加到SPN,此代码就可以针对另一领域中的服务,如HTTP/webservice-host.otherdomain.ltd@OTHERDOMAIN.LTD
对于其他领域中已知的用户,您应该将其附加到方法createName("targetUser@OTHERDOMAIN.LTD", GSSName.NT_USER_NAME)
中的登录名