我在Web应用程序中使用Waffle作为SSO解决方案。
一切正常,但我想稍微修改一些功能:
当前,如果用户未连接到域,则SSO失败并打开一个小的授权对话框:
Windows授权要求使用类似于Domain\Username
格式的用户名,但是我的大多数用户都不知道将域添加到用户名之前。因此,如果未指定默认域名,我想提供一个默认域名。
我找到了一个可以覆盖的waffle函数,它将使我能够访问已解码的身份验证令牌,我在waffle函数中添加了println
,并以纯文本形式显示了用户名(根据输入的内容而定,是否包含域)在对话框中):
public IWindowsSecurityContext acceptSecurityToken(String connectionId, byte[] token, String securityPackage) {
// I can see the passed username in the logs with this
System.out.println(new String(token));
// I don't understand any of the JNA stuff below this comment:
IWindowsCredentialsHandle serverCredential = new WindowsCredentialsHandleImpl(
null, Sspi.SECPKG_CRED_INBOUND, securityPackage);
serverCredential.initialize();
SecBufferDesc pbServerToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, token);
NativeLongByReference pfClientContextAttr = new NativeLongByReference();
CtxtHandle continueContext = _continueContexts.get(connectionId);
CtxtHandle phNewServerContext = new CtxtHandle();
int rc = Secur32.INSTANCE.AcceptSecurityContext(serverCredential.getHandle(),
continueContext, pbClientToken, new NativeLong(Sspi.ISC_REQ_CONNECTION),
new NativeLong(Sspi.SECURITY_NATIVE_DREP), phNewServerContext,
pbServerToken, pfClientContextAttr, null);
WindowsSecurityContextImpl sc = new WindowsSecurityContextImpl();
sc.setCredentialsHandle(serverCredential.getHandle());
sc.setSecurityPackage(securityPackage);
sc.setSecurityContext(phNewServerContext);
switch (rc)
{
case W32Errors.SEC_E_OK:
// the security context received from the client was accepted
_continueContexts.remove(connectionId);
// if an output token was generated by the function, it must be sent to the client process
if (pbServerToken != null
&& pbServerToken.pBuffers != null
&& pbServerToken.cBuffers.intValue() == 1
&& pbServerToken.pBuffers[0].cbBuffer.intValue() > 0) {
sc.setToken(pbServerToken.getBytes());
}
sc.setContinue(false);
break;
case W32Errors.SEC_I_CONTINUE_NEEDED:
// the server must send the output token to the client and wait for a returned token
_continueContexts.put(connectionId, phNewServerContext);
sc.setToken(pbServerToken.getBytes());
sc.setContinue(true);
break;
default:
sc.dispose();
WindowsSecurityContextImpl.dispose(continueContext);
_continueContexts.remove(connectionId);
throw new Win32Exception(rc);
}
return sc;
}
整个功能来自Waffle API,我只是在开始时添加了println。
传递的用户名在一堆随机字节字符(ÉsR=ÍtÍö?æ¸+Û-)之间的令牌中以纯文本格式打印。
一般而言,我对JNA和Java的了解远远超出了我的范围,但我认为因为可以在此处看到用户名,因此必须有一种方法可以将域名添加到此令牌的用户名部分?我可能是错的。
我的另一个想法是将域添加到通过此方法传递的原始byte []令牌创建的
pbClientToken
中。pbClientToken
是JNA Structure
object派生词。它具有Stucture
方法writeField
看起来很有希望,但是我似乎无法弄清楚应该写哪个字段。 Structure.getFields
似乎无法使用pbClientToken
方法。我希望对于熟悉byte []处理或JNA的人来说,这是一个简单的问题。
最佳答案
你不可以做这个。在此对话框后面发生的是在用户计算机上调用LogonUser的操作,该操作会给您一张票证,然后将其发送到服务器。不幸的是,服务器不在同一域中,因此即使您设法提取用户名,它也完全没有用。
关于java - 将域名插入servlet身份验证 token ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11853433/