java - 在 Java 中使用 Waffle 获取 Kerberos 服务票证
问题描述
我正在在 Windows 10 上运行的 Java 应用程序中开发真正的 SSO。我的应用程序已经使用 Java 的 GSSAPI 进行了 Kerberos 身份验证(但它显然不适用于任何现代 Windows,尤其是在具有严格的安全策略和域用户的情况下),所以我想用 Waffle 替换当前的授权系统,对整体应用程序设计的影响最小——我认为如果我能以某种方式获得 KerberosTicket 实例,这应该是可能的。我正在努力编写这个功能,到目前为止我设法请求了一些令牌,但我真的不知道这个令牌是什么,它与 Kerberos 票证格式不匹配。这是我的(实际上更像是在网上找到的代码):
public byte[] getServiceTicketSSPI() {
final String securityPackage = "Kerberos";
final String targetName = "<disclosed>";
IWindowsCredentialsHandle clientCredentials = null;
WindowsSecurityContextImpl clientContext = null;
final String currentUser = WindowsAccountImpl.getCurrentUsername();
try {
clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
clientCredentials.initialize();
// initial client security context
clientContext = new WindowsSecurityContextImpl();
clientContext.setPrincipalName(currentUser);
clientContext.setCredentialsHandle(clientCredentials);
clientContext.setSecurityPackage(securityPackage);
final Sspi.SecBufferDesc continueToken = null;
do {
if(debug)
System.out.println("Using target name: " + targetName);
clientContext.initialize(clientContext.getHandle(), continueToken, targetName);
} while(clientContext.isContinue());
return clientContext.getToken();
} finally {
if (clientContext != null)
clientContext.dispose();
if (clientCredentials != null)
clientCredentials.dispose();
}
}
公平地说,我什至不确定 SSPI 是否允许我真正看到真正的票。我什至会在这个片段中朝着正确的方向前进吗?我会很高兴的,所以看看我应该做什么的任何线索。最后拥有 KerberosTicket 实例将是完美的。
解决方案
以下是在不使用服务器的情况下使用独立 Java 客户端的 Waffle 进行单点登录的步骤。
创建客户端凭据 使用 WindowsSecurityContextImpl 的 initializeSecurityContext 获取服务票证。使用 WindowsAuthProviderImpl 的 accessSecurityContext 获取 WindowsIdentity 原文链接https://exceptionhub.com/getting-kerberos-service-ticket-using-waffle-in-java.html
对于客户端-服务器 sso,您应该遵循https://code.dblock.org/2010/04/08/pure-java-waffle.html下面的代码描述了使用 kerberos 的独立 java sso。
import com.sun.jna.platform.win32.Sspi;
import waffle.windows.auth.IWindowsCredentialsHandle;
import waffle.windows.auth.IWindowsIdentity;
import waffle.windows.auth.IWindowsSecurityContext;
import waffle.windows.auth.impl.WindowsAccountImpl;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;
import waffle.windows.auth.impl.WindowsCredentialsHandleImpl;
import waffle.windows.auth.impl.WindowsSecurityContextImpl;
public class KerberosSingleSignOn {
public static void main() {
try {
System.out.println(getWindowsIdentity().getFqn());
}
catch (Exception e) {
e.printStackTrace();
}
}
public static IWindowsIdentity getWindowsIdentity() throws Exception {
try {
byte[] kerberosToken = getServiceTicketSSPI();
WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
IWindowsSecurityContext securityContext = provider
.acceptSecurityToken("client-connection", kerberosToken, "Kerberos");
return securityContext.getIdentity();
}
catch (Exception e) {
throw new Exception("Failed to process kerberos token");
}
}
public static byte[] getServiceTicketSSPI() throws Exception {
final String securityPackage = "Kerberos";
IWindowsCredentialsHandle clientCredentials = null;
WindowsSecurityContextImpl clientContext = null;
final String currentUser = WindowsAccountImpl.getCurrentUsername();
try {
clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage);
clientCredentials.initialize();
// initial client security context
clientContext = new WindowsSecurityContextImpl();
clientContext.setCredentialsHandle(clientCredentials.getHandle());
/*OR
clientContext.setCredentialsHandle(clientCredentials);
*/
clientContext.setSecurityPackage(securityPackage);
final Sspi.SecBufferDesc continueToken = null;
do {
System.out.println("Using current username: " + currentUser);
clientContext.initialize(clientContext.getHandle(), continueToken, currentUser);
}
while (clientContext.isContinue());
return clientContext.getToken();
}
catch (Exception e) {
throw new Exception("Failed to process kerberos token");
}
finally {
if (clientContext != null)
clientContext.dispose();
if (clientCredentials != null)
clientCredentials.dispose();
}
}
}
推荐阅读
- c# - 将 TextBox 绑定到 ListBox SelectedItem
- google-chrome - Sublime Text 3 + Markdown Preview / Chrome 不渲染数学方程
- python - ValueError:检查输入时出错:预期 input_2 的形状为 (128, 173, 1) 但得到的数组的形状为 (128, 173, 3)
- gtk - 如何在不窃取其事件的情况下在小部件上绘制矩形?
- ruby-on-rails - Rails config.cache_store 这个值计算为 nil 会发生什么?
- sass - 我的 WebCompiler 扩展使用哪个版本的 SASS?
- node.js - Angular SSR 构建命令失败
- android-studio - 渲染问题:找不到以下类
- javascript - 给定一个包含不同项目的 n 项目数组 [a1, a2, ..., an],是否有一种简单的方法可以生成选择 0 到 k 个项目的所有组合?
- java - 在 JComponent 处创建阴影的颜色与白色不同的问题