问题描述
我一直试图了解这些不同的 API 如何在幕后粘合在一起。虽然这个问题可能看起来很宽泛,但我也想了解一个特定的场景。对此可以进一步调试的任何指针将不胜感激。
我正在学习这个基本教程 - https://docs.oracle.com/javase/jndi/tutorial/ldap/security/src/Mutual.java
在此,我特别想了解,在创建 DirContext
// 请求使用“GSSAPI”SASL 机制 使用已经建立的 Kerberos 凭证进行身份验证 env.put(Context.Security_AUTHENTICATION,"GSSAPI");
当环境哈希表中的 Context.Security_AUTHENTICATION
设置为 GSSAPI
时,在创建 DirContext/LDAPContext 期间执行的高级步骤是什么?
让我们从头开始:
LoginContext lc = new LoginContext(...)
lc.login()
这段代码的作用是,它与KDC服务器通信,并从中获取TGT,如果认证成功!登录上下文中有一个 Subject(authenticated) 填充在其中,其中包含凭据的所有信息。
一旦完成,以下代码将用于执行 JNDI。
-
将代码作为 Subject 的 PrivilegedAction 执行如下究竟意味着什么?
Subject.doAs(lc.getSubject(),new JndiAction(args));
我无法理解从 Subject.doAs(...) 返回的对象会发生什么?
场景:
-
考虑到 DirContext 是由 Subject.doAs(...) 方法通过使用 PrivilegedAction{....} 返回的,以便稍后可以使用上下文。
-
如果创建它的主体是
logged out
或其credentials are invalidated or changed?
,此上下文会发生什么情况,它仍会继续工作吗? -
TGT 是否用于后面的任何
ctx
操作,如 search() 或图片中的 GSSAPI 是否用于任何这些操作? -
Active Directory 如何验证此上下文是否有效?
要求
一个。我们不想在 PrivilegedAction#run
中执行任何 JNDI 操作。我们只想返回我们想要缓存或稍后使用的 context
对象。
B.由于某些原因,我们有一个特殊的要求,我们不能对单个 krb.conf
文件提出要求。我们为每个后续请求创建和销毁 krb.conf。
c.我问问题 #5 的原因是 - 一旦 krb.conf 文件按照上面的解释重新生成,来自内存中 LoginContext#Subject
对象的所有凭据都将失效,无法进一步使用。
d。在这种情况下,我们可以使用缓存的上下文吗?
对理解实际工作的任何帮助表示赞赏
解决方法
我特别想了解,在创建 DirContext 期间,这行实际上意味着什么
// Request the use of the "GSSAPI" SASL mechanism Authenticate by using already established Kerberos credentials
env.put(Context.SECURITY_AUTHENTICATION,"GSSAPI");
这部分很简单,就是告诉ldap客户端使用
GSSAPI 身份验证,而不是“简单”或“无”。
虽然理论上“GSSAPI”应该支持一系列不同的实现,
在这个 Java 实现中,它只支持 kerberosV5。
简单的身份验证,只需将用户名/密码直接传递给 LDAP 服务器。
如果 LDAP 服务器不需要查询身份验证,则不会。
GSSAPI,这里使用之前获取的主题中存储的kerberos凭证。
- 此
LDAPContext
创建是否需要主题的 TGT?
这将取决于 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);
LoginContext#login() 过程中获取的 Subject 的 TGT/Subject/Private-public 凭证的作用是什么?
在原始示例中,它们用于获取与 LDAP 服务器一起使用的服务票证。
将代码作为 Subject 的 PrivilegedAction 执行如下究竟意味着什么?
Java 的 SecurityManager
架构复杂且陈旧,
没有深入了解所有细节,这里发生的事情或多或少,
只是使 Subject
对象可用于在特权操作中运行的代码。
当 kerberos 代码查找凭据时,
it checks the AccessControlContext
and uses credentials from it if available。
- 考虑 DirContext 是由 Subject.doAs(...) 方法返回的 通过使用 PrivilegedAction{....} 以便稍后可以使用上下文。
凭据/票证未绑定到 DirContext
对象,
因此,如果不使用 Subject.doAs
,它将无法继续工作。
- 如果它通过的主题,这个上下文会发生什么 created 已注销或其凭据无效或更改?它还会继续工作吗?
如果用户是 注销或禁用,将取决于 ldap 服务器实现。
- TGT 是否用于任何后续的 ctx 操作,如 search() 或者图片中的 GSSAPI 是否用于任何这些操作?
它们可以,但您需要通过 Subject.doAs
访问它们,
它们没有附加到 DirContext
。
第一次访问上下文时,将使用 TGT 获取服务票证, 并且该服务票在有效期间将继续使用。
一个。我们不想在 PrivilegedAction#run 中执行任何 JNDI 操作。 我们只想返回我们想要缓存或稍后使用的上下文对象。
应该可以使用简单的身份验证。
您还可以选择使用系统 kerberos 凭据缓存,但我想这会带来更多的工作,并且需要处理更多的文件。
B.由于某些原因,我们对单个 krb.conf 文件有一个特殊的要求。 我们为每个后续请求创建和销毁 krb.conf。
这并不理想,遗憾的是 Java kerberos 实现不支持任何更好的方式来使用多个 kerberos 配置。
c.我问问题 #5 的原因是 - 一旦 krb.conf 文件如上所述重新生成, 来自内存中 LoginContext#Subject 对象的所有凭据都已失效,无法进一步使用。
不正确,凭据仍然有效,但您需要将 krb.conf 更改回正确的设置 您正在使用的主题,因为在初始登录后仍会引用配置文件。
d。在这种情况下,我们可以使用缓存的上下文吗?
是的,但您需要先将 krb5.conf 更改回正确的值。
您可以在使用上下文之前手动调用 sun.security.krb5.Config.refresh();
,以确保加载文件配置。
配置通常只在登录时刷新。