在 Java 中使用 kerberos 票证获取 AD 组
我正在获取带有以下代码的 kerberos 票证:
I am obtaining a kerberos ticket with the following code:
String client = "com.sun.security.jgss.krb5.initiate";
LoginContext lc = new LoginContext(client, new CallbackHandler() {
@Override
public void handle(Callback[] arg0) throws IOException, UnsupportedCallbackException {
System.out.println("CB: " + arg0);
}
});
lc.login();
System.out.println("SUBJ: " + lc.getSubject());
此代码运行良好,我得到一个显示我的用户 ID 的主题.我现在遇到的问题是我需要知道用户是否属于 AD 中的某个组.有没有办法从这里做到这一点?
This code works fine, I get a subject that shows my user ID. The problem I'm having is now I need to know whether the user belongs to a certain group in AD. Is there a way to do this from here?
我已经看到使用 LDAP 获取用户组的代码,但它需要使用用户/密码登录,我需要以 SSO 方式进行.
I've seen code to get user groups using LDAP but it requires logging in with a user/password, I need to do it the SSO way.
推荐答案
您实际上无法使用登录时获得的票证来执行此操作.问题是 Windows PAC(包含组成员信息)位于票证的加密部分.只有域控制器知道如何解密初始票证.
You cannot actually do this with the kind of ticket you get at login. The problem is that the Windows PAC (which contains the group membership information) is in the encrypted part of the ticket. Only the domain controller knows how to decrypt that initial ticket.
可以使用服务票.因此,您可以设置一个密钥表,使用 jgss 对自己进行身份验证,然后解密票证,找到 PAC,解码 PAC,然后处理 SID.我无法在 Java 中找到大部分代码,尽管它在 C 中可用.看看 this 了解如何解密票证.现在,此时您正在谈论编写或查找 NDR 解码器,阅读有关如何将 PAC 和 sid 组合在一起的所有规范,或者将 C 代码移植到 Java.我的建议是采取不同的方法.而是使用 Kerberos 登录 LDAP.查找支持 Java 的 LDAP 库 SASL 并且您应该能够使用 Kerberos 票证登录.
It is possible to do with a service ticket. So, you could set up a keytab, use jgss to authenticate to yourself and then decrypt the ticket, find the PAC, decode the PAC and then process the SIDs. I wasn't able to find code for most of that in Java, although it is available in C. Take a look at this for how to decrypt the ticket. Now, at this point you're talking about writing or finding an NDR decoder, reading all the specs about how the PAC and sids are put together, or porting the C code to Java. My recommendation would be to take a different approach. Instead, use Kerberos to sign into LDAP. Find an LDAP library that supports Java SASL and you should be able to use a Kerberos ticket to log in.
如果您的应用程序想知道用户所属的组以填充菜单和类似的东西,您只需以用户身份登录即可.但是,如果您要决定用户拥有什么访问权限,请不要以用户身份登录以获得对 LDAP 的访问权限.问题在于,使用 Kerberos,攻击者可以与用户合作,将整个基础架构模拟到您的应用程序中,除非您确认您的票证来自基础架构.也就是说,因为用户知道他们的密码,并且因为这是您的应用程序知道的唯一秘密,所以用户可以与某人合作伪装成 LDAP 服务器并声称拥有他们想要的任何访问权限.
If your application wants to know the groups the user belongs to in order to populate menus and stuff like that, you can just log in as the user. However, if you're going to decide what access the user has, don't log in as the user to gain access to LDAP. The problem is that with Kerberos, an attacker can cooperate with the user to impersonate the entire infrastructure to your application unless you confirm that your ticket comes from the infrastructure. That is, because the user knows their password, and because that's the only secret your application knows about, the user can cooperate with someone to pretend to be the LDAP server and claim to have any access they want.
相反,您的应用程序应该在访问 LDAP 时使用自己的帐户.如果你这样做,你可以只查找组列表.我确实意识到这有点复杂.
Instead, your application should have its own account to use when accessing LDAP. If you do that, you can just look up the group list. I do realize this is all kind of complex.
相关文章