我有一个Java Web应用程序,它在Windows Active Directory环境中对客户端进行SPNEGO身份验证.
为了验证用户,我们使用了旧的SPNEGO SourceForge项目中的代码.
String encodedAuthToken = (String) credentials;
LOG.debug("Encoded auth token: " + encodedAuthToken);
byte[] authToken = B64Code.decode(encodedAuthToken);
GSSManager manager = GSSManager.getInstance();
try {
Oid krb5Oid = new Oid("1.3.6.1.5.5.2");
GSSName gssName = manager.createName(_targetName, null);
GSSCredential serverCreds = manager.createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, krb5Oid, GSSCredential.INITIATE_AND_ACCEPT);
GSSContext gContext = manager.createContext(serverCreds);
if (gContext != null) {
while (!gContext.isEstablished()) {
authToken = gContext.acceptSecContext(authToken, 0, authToken.length);
}
if (gContext.isEstablished()) {
// Login succeeded!
String clientName = gContext.getSrcName().toString();
}
}
}
身份验证工作正常,但我们还要求使用约束委派将用户凭据委派给后端服务(Exchange EWS).
在我们的AD中配置它时,它看起来像一个小差异,但事实并非如此.看到:
AD delegation settings
不同之处在于:msdn.microsoft.com/en-us/library/cc246080.aspx?f=255\u0026amp;MSPPError=-2147217396
通过无约束委派,我们可以在调用后端服务时简单地使用可用的委派凭据,这一切都很好:
GSSCredential delegatedCreds = gContext.getDelegCred()
SpnegoHttpURLConnection conn = new SpnegoHttpURLConnection(clientCreds);
通过约束委派,我们无法访问用户TGT,似乎我们需要使用Java 8支持的MS-SFU(S4U2proxy)Kerberos扩展.
我能找到的唯一例子是这一个:https://github.com/ymartin59/java-kerberos-sfudemo(感谢Yves Martin!)
现在我的问题…在我的身份验证后,我基本上得到了经过身份验证的用户的用户名(请参阅上面代码中的“clientName”).
我们真的需要使用S4U2self机制来冒充用户吗?
客户端刚刚向我们发送了Kerberos Service Ticket(包含在我无法解码的SPNEGO令牌中).
理想情况下,我们应该能够使用该服务票证和我自己的服务的TGT来验证用户(使用S4U2proxy机制)?
但我不明白怎么做.
那么现在我想知道是否可以将我们的SPNEGO身份验证与S4U2proxy委派联系在一起?
非常感谢您对此提出的任何意见.
解决方法:
我最近一直在做这样的事情,但我正在使用春天安全kerberos.我在github here上举了一个例子.关键是我发现我需要设置使用约束委托,就像你想要它和S4U2Proxy一样,确保(如果你使用的是Oracle / OpenJDK)你在你的设置中设置isInitiator = true JAAS Config,这样当调用getDelegCred时,你会得到一个Krb5ProxyCredential.请参阅注释here.使用该凭据,您可以使用它来代表用户创建服务票证令牌,以限制您以正常方式使用的服务,例如this.