使用Java中的kerberos票证获取AD组

时间:2013-11-22 18:32:14

标签: java ldap single-sign-on kerberos

我正在使用以下代码获取kerberos票证:

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中的某个组。有没有办法从这里做到这一点?

我见过使用LDAP获取用户组的代码,但需要使用用户/密码登录,我需要以SSO的方式进行操作。

1 个答案:

答案 0 :(得分:1)

您无法使用登录时获得的票证来实现此目的。问题是Windows PAC(包含组成员身份信息)位于故障单的加密部分。只有域控制器知道如何解密该初始票证。

可以使用服务票证。 因此,您可以设置密钥表,使用jgss对自己进行身份验证,然后解密故障单,找到PAC,解码PAC,然后处理SID。我无法在Java中找到大部分代码,尽管它在C中可用。请查看this以了解如何解密故障单。 现在,此时您正在讨论编写或查找NDR解码器,阅读有关如何将PAC和sid放在一起的所有规范,或将C代码移植到Java。 我的建议是采取不同的方法。 而是使用Kerberos登录LDAP。找到支持Java SASL的LDAP库,您应该能够使用Kerberos票证登录。

如果您的应用程序想知道用户所属的组以填充菜单和类似的东西,您只需以用户身份登录即可。 但是,如果您要决定用户具有哪些访问权限,请不要以用户身份登录以获得对LDAP的访问权限。问题是,使用Kerberos,攻击者可以与用户合作,将整个基础架构模拟到您的应用程序,除非您确认您的票证来自基础架构。 也就是说,因为用户知道他们的密码,并且因为这是您的应用程序知道的唯一秘密,所以用户可以与某人合作伪装成LDAP服务器并声称拥有他们想要的任何访问权。

相反,您的应用程序在访问LDAP时应该拥有自己的帐户。如果这样做,您只需查找组列表即可。 我确实意识到这有点复杂。