我在我的网络应用程序中使用Waffle作为 SSO 解决方案。
一切正常,但我想稍微修改一些功能:
目前,如果用户未连接到域,SSO 将失败并打开一个小授权对话框:
Windows 授权需要用户名格式,Domain\Username
但我的大多数用户不知道在他们的用户名前面添加域。因此,如果未指定,我想提供一个默认域名。
我找到了一个可以覆盖的 waffle 函数,它可以让我访问解码的身份验证令牌,我println
在 waffle 函数中添加了一个,它以纯文本形式显示用户名(有或没有域,具体取决于在对话框中键入的内容) ):
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 的理解非常遥远,但我认为因为我可以在这里看到用户名,所以必须有一种方法可以将域名添加到此令牌的用户名部分?我可能是错的。
我的另一个想法是将域添加到pbClientToken
从传递此方法的原始字节 [] 令牌创建的域中。
是JNA对象派生类pbClientToken
。它的方法看起来很有希望,但我似乎无法弄清楚我应该写什么领域。该方法似乎不适用于.Structure
Stucture
writeField
Structure.getFields
pbClientToken
我希望这对于更熟悉 byte[] 处理或 JNA 的人来说是一个简单的问题。