了解和探索 JAAS-GSSAPI-JNDI 如何在幕后协同工作

Understanding and exploring how JAAS-GSSAPI-JNDI work together behind the hood

我一直在努力了解这些不同的 API 如何在幕后粘合在一起。虽然这个问题看起来很宽泛,但我也想了解一个特定的场景。对此可以进一步调试的任何指示将不胜感激。

我正在学习这个基本教程 - https://docs.oracle.com/javase/jndi/tutorial/ldap/security/src/Mutual.java

在此,我特别想了解,在创建 DirContext

期间,这行实际上意味着什么

// Request the use of the "GSSAPI" SASL mechanism Authenticate by using already established Kerberos credentials env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");

当在环境哈希表中 Context.SECURITY_AUTHENTICATION 设置为 GSSAPI 时,创建 DirContext/LDAPContext 期间执行的高级步骤是什么?

  1. LDAPContext 创建需要主题的 TGT 吗?
  2. LoginContext#login() 过程中获取的 Subject TGT/Subject/Private-public 凭据的作用是什么?

让我们从头说起:

 LoginContext lc = new LoginContext(...)
 lc.login() 

这段代码的作用是,与KDC服务器通信,如果认证成功,从中获取一个TGT!登录上下文中填充了一个 Subject(authenticated),其中包含 Credentials 的所有信息。

完成后,使用以下代码执行 JNDI。

  1. 执行如下代码作为Subject的PrivilegedAction究竟是什么意思?

    Subject.doAs(lc.getSubject(), new JndiAction(args));
    

我无法理解从 Subject.doAs(...)?

返回的对象会发生什么

场景:

  1. 考虑到 DirContext 是由 Subject.doAs(...) 方法通过使用 PrivilegedAction{....} 返回的,以便以后可以使用上下文。

  2. 如果创建它的 Subject 是 logged out 或者它的 credentials are invalidated or changed? 这个上下文会发生什么,它还会继续工作吗?

  3. TGT 是否用于任何后来的 ctx 操作,如 search() 或图片中的 GSSAPI 是否用于任何这些操作?

  4. 活动目录如何验证此上下文有效?


要求

a. We don't want to perform any JNDI operation within the PrivilegedAction#run. We just want to return the context object which we want to cache or use later.

b. We have a peculiar requirement that we can't have on single krb.conf file due to some reasons. We create and destroy krb.conf for every subsequent request.

c. The reason for me asking question #5 is that - once the krb.conf file is re-generated as explained above, all the credentials from the in-memory LoginContext#Subject objects are invalidated and can't be used further.

d. In this case, can we use the cached context?

感谢任何有助于理解实际工作的帮助

I am particularly trying to understand, what this line actually means, during the creation of DirContext

// Request the use of the "GSSAPI" SASL mechanism Authenticate by using already established Kerberos credentials 
env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");

这部分很简单,就是告诉ldap客户端使用 GSSAPI 身份验证,而不是“简单”或“none”。
虽然理论上“GSSAPI”应该支持一系列不同的实现, 在此 Java 实现中,它仅支持 kerberosV5。
简单的身份验证,只是将 username/password 直接传递给 LDAP 服务器。
None 是,如果 LDAP 服务器不需要查询身份验证。
GSSAPI,这里使用之前获取的subject中存储的kerberos凭证。

  1. Is the TGT of the Subject required for this LDAPContext creation?

这将取决于 LDAP 服务器配置,但一般来说,不,这不是必需的。

要使用简单的身份验证,您可以执行以下操作:

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PRINCIPAL, "Administrator@corp.example.com");
env.put(Context.PROVIDER_URL, "ldap://WIN-MKR9VI69FT4.corp.example.com/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_CREDENTIALS, "password".toCharArray());
DirContext ctx = new InitialDirContext(env);

What is the role of the TGT/Subject/Private-public credentials of the Subject acquired during the LoginContext#login() process?

在最初的示例中,它们用于获取与 LDAP 服务器一起使用的服务票证。

What does it actually mean to execute the code as the PrivilegedAction of the Subject as follows?

Java 的 SecurityManager 架构复杂且陈旧, 在不深入了解所有细节的情况下,这里发生的事情或多或少是, 只是让 Subject 对象可用于在特权操作中运行的代码。

当 kerberos 代码查找凭据时, it checks the AccessControlContext and uses credentials from it if available.

  1. Consider that the DirContext is returned by the Subject.doAs(...) method by using PrivilegedAction{....} so that the context can be used later on.

credentials/ticket 未绑定到 DirContext 对象, 所以它不会继续工作,不使用 Subject.doAs.

  1. What will happen to this context if the Subject through which it was created was logged out or its credentials are invalidated or changed? Will it still continue to work?

如果用户是,credentials/ticket 可能会或可能不会继续工作 注销或禁用,将取决于 ldap 服务器实现。

  1. Are the TGTs used for any of the later ctx operations like search() or is the GSSAPI in the picture for any of these operations?

它们可以,但您需要通过 Subject.doAs 访问它们, 他们没有附加到 DirContext.

第一次访问上下文时,将使用 TGT 获取服务票证, 只要该服务票有效,它就会继续使用。

a. We don't want to perform any JNDI operation within the PrivilegedAction#run. We just want to return the context object which we want to cache or use later.

应该可以使用简单的身份验证。
您还可以选择使用系统 kerberos 凭据缓存,但我想这会工作更多,并且需要处理更多文件。

b. We have a peculiar requirement that we can't have on single krb.conf file due to some reasons. We create and destroy krb.conf for every subsequent request.

这并不理想,遗憾的是 Java kerberos 实现不支持任何更好的方式来使用多个 kerberos 配置。

c. The reason for me asking question #5 is that - once the krb.conf file is re-generated as explained above, all the credentials from the in-memory LoginContext#Subject objects are invalidated and can't be used further.

不正确,凭据仍然有效,但您需要将 krb.conf 更改回正确的设置 您正在使用的主题,因为在初始登录后仍会引用配置文件。

d. In this case, can we use the cached context?

可以,但是您需要先将 krb5.conf 改回正确的值。
您可以在使用上下文之前手动调用 sun.security.krb5.Config.refresh();,以确保加载文件配置。
配置通常只在登录时刷新。