主要编辑:2015-05-27:在取得了一定程度的成功后,我更新了我目前卡住的地方,而不是留下一个漫无边际的帖子……真的可以用一些指针来解决这个问题——有点陷入困境……
我正在 Linux 应用程序服务器 (WebSphere) 上运行一些代码,这些代码需要对配置为“集成身份验证”的 IIS Web 服务进行身份验证,但是在形成授权:协商令牌时遇到了一些问题。我还应该说,我需要将此令牌放入随后将构建的 JAX-WS SOAP 请求的 HTTP 标头中。我知道我的 SOAP 请求本身可以工作,因为我们之前使用的是 WS-Security 用户名令牌配置文件并且它工作得很好 - 尝试交换到 kerberos 被证明是困难的......
我认为我的问题是 initSecContext 。似乎在第一次调用时,上下文是以“某种”方式配置的,并且有一些返回的令牌数据,但 .isEstablished 是错误的。我遇到的问题是将 initSecContext 调用放入一个循环中 - 当我这样做时,似乎 IIS 只是关闭了连接。任何人都可以给我一些指示 - 我似乎正在采用其他海报和 Oracle 示例使用的方法(尽管 IBM/WebSphere 示例只进行了一次 initSecContext 调用并且不检查 .isEstablished 对我来说这似乎很奇怪基于Oracle 文档)。
无论如何,我得到的错误如下(注意 Ready: 属性似乎清楚地说 initSecContext 需要循环 - 至少对我来说);
[5/27/15 6:51:11:605 UTC] 0000004f SystemOut O INFO: com.mycorp.kerberosKerberosTokenGenerator/getKerberosToken/run: After initSecContext:
--- GSSContext ---
Owner: domainuser@MYDOMAIN.COM
Peer: HTTP/iishost.mycorp.com
State: initialized
Lifetime: indefinite
Ready: no
Flags:
Confidentiality off
Delegation on
Integrity off
MutualAuthn on
ReplayDetection off
SequenceDetection off
DelegatedCred: unknown
--- End of GSSContext ---
[5/27/15 6:51:11:605 UTC] 0000004f SystemOut O INFO: com.mycorp.kerberosKerberosTokenGenerator/getKerberosToken/run: Context is not established, trying again
[5/27/15 6:51:11:606 UTC] 0000004f SystemOut O ERROR: com.mycorp.kerberosKerberosTokenGenerator/getKerberosToken/run: IOException during context establishment: Connection reset
我的代码如下;
LoginContext lc = getLoginContext(contextName);
final Subject subject = lc.getSubject();
String b64Token = (String) Subject.doAs(subject, new PrivilegedExceptionAction() {
@Override
public Object run() throws PrivilegedActionException, GSSException {
// Create socket to server
Socket socket;
DataInputStream inStream = null;
DataOutputStream outStream = null;
try {
socket = new Socket("iishost.mycorp.com", 443);
inStream = new DataInputStream(socket.getInputStream());
outStream = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
System.out.println("Exception setting up server sockets: " + ex.getMessage());
}
GSSName gssName = manager.createName(userName, GSSName.NT_USER_NAME, KRB5_MECH_OID);
GSSCredential gssCred = manager.createCredential(gssName.canonicalize(KRB5_MECH_OID),
GSSCredential.DEFAULT_LIFETIME,
KRB5_MECH_OID,
GSSCredential.INITIATE_ONLY);
gssCred.add(gssName, GSSCredential.INDEFINITE_LIFETIME,
GSSCredential.INDEFINITE_LIFETIME,
SPNEGO_MECH_OID,
GSSCredential.INITIATE_ONLY);
GSSName gssServerName = manager.createName(servicePrincipal, KERBEROS_V5_PRINCIPAL_NAME);
GSSContext clientContext = manager.createContext(gssServerName.canonicalize(SPNEGO_MECH_OID),
SPNEGO_MECH_OID,
gssCred,
GSSContext.DEFAULT_LIFETIME);
clientContext.requestCredDeleg(true);
clientContext.requestMutualAuth(true);
byte[] token = new byte[0];
while (!clientContext.isEstablished()) {
try {
token = clientContext.initSecContext(token, 0, token.length);
// IF I LOOK AT token HERE THERE IS CERTAINLY TOKEN DATA THERE - .isEstablished IS STILL FALSE
outStream.writeInt(token.length);
outStream.write(token);
outStream.flush();
// Check if we're done
if (!clientContext.isEstablished()) {
token = new byte[inStream.readInt()];
inStream.readFully(token);
}
} catch (IOException ex) {
// THIS EXCEPTION IS THROWN ON SECOND ITERATION - LOOKS LIKE IIS CLOSES THE CONNECTION
System.out.println("IOException during context establishment: " + ex.getMessage());
}
}
String b64Token = Base64.encode(token);
clientContext.dispose(); // I'm assuming this won't invalidate the token in some way as I need to use it later
return b64Token;
}
});
该文档告诉我不需要循环 initSecContext,但 .isEstablished 为我返回 false:http://www-01.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.zseries。 doc/ae/tsec_SPNEGO_token.html?cp=SS7K4U_8.5.5%2F1-3-0-20-4-0&lang=en
Oracle 文档告诉我应该:https ://docs.oracle.com/javase/7/docs/api/org/ietf/jgss/GSSContext.html
我唯一的犹豫是,从 Oracle 文档看来,我正在开始应用程序对话,但我试图做的只是获取令牌,稍后在我的代码中使用 JAX-WS 发布我的实际的 Web 服务调用(包括 http 标头中的 spnego/kerberos 令牌) - 这是我的问题的原因吗?