JNDI 搜索在 GSSAPI 之后不起作用(使用 Kerberos 进行身份验证)
JNDI search not working after GSSAPI (Authenticate with Kerberos)
我从互联网上得到了下面的例子,用 JNDI 测试 GSSAPI。
public class GssExample {
public static void main(String[] args) {
System.setProperty("java.security.auth.login.config", "C:\gssapi_jaas.conf");
System.setProperty("java.security.krb5.conf", "C:\krb5.conf");
LoginContext lc = null;
try {
lc = new LoginContext(GssExample.class.getName(),
new LoginCallBackHandler());
lc.login();
} catch (LoginException le) {
}
Subject.doAs(lc.getSubject(), new JndiAction(args));
}
}
class JndiAction implements java.security.PrivilegedAction {
public Object run() {
performJndiOperation(args);
return null;
}
private static void performJndiOperation(String[] args) {
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL,
"ldap://XXXX.domain.lab:389/OU=Whosebug,dc=domain,dc=lab");
env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
env.put("javax.security.sasl.server.authentication", "true");
try {
DirContext ctx = new InitialDirContext(env);
// Fails here with exception as shown below
NamingEnumeration<SearchResult> _result = ctx.search("DC=domain,DC=lab","(objectClass=User)", null);
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
我得到异常
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D:
NameErr: DSID-03100241, problem 2001 (NO_OBJECT), data 0, best match
of: 'OU=Whosebug,DC=domain,DC=lab'
请注意:该 OU 存在于 AD 系统中。
LoginCallBackHandler
的代码如下
class LoginCallBackHandler implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
if(callbacks != null && callbacks.length > 0) {
if(callbacks[0] instanceof NameCallback) {
((NameCallback)(callbacks[0])).setName("User@DOMAIN.LAB");
}
else if(callbacks[0] instanceof PasswordCallback) {
((PasswordCallback)(callbacks[0])).setPassword("Password".toCharArray());
}
}
}
}
我是漏掉了什么还是做错了什么?
该错误与身份验证无关。您错误地使用了 LDAP 搜索。您已经限制了搜索基础 DN ldap://XXXX.domain.lab:389/OU=Whosebug,dc=domain,dc=lab
。然后您提供了 ctx.search("DC=domain,DC=lab",...
,但没有树 DC=domain,DC=lab,OU=Whosebug,dc=domain,dc=lab
。
要么提供另一个仅具有 RootDSE 的 LDAP URL,要么向 search()
.
提供一个空字符串
我从互联网上得到了下面的例子,用 JNDI 测试 GSSAPI。
public class GssExample {
public static void main(String[] args) {
System.setProperty("java.security.auth.login.config", "C:\gssapi_jaas.conf");
System.setProperty("java.security.krb5.conf", "C:\krb5.conf");
LoginContext lc = null;
try {
lc = new LoginContext(GssExample.class.getName(),
new LoginCallBackHandler());
lc.login();
} catch (LoginException le) {
}
Subject.doAs(lc.getSubject(), new JndiAction(args));
}
}
class JndiAction implements java.security.PrivilegedAction {
public Object run() {
performJndiOperation(args);
return null;
}
private static void performJndiOperation(String[] args) {
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL,
"ldap://XXXX.domain.lab:389/OU=Whosebug,dc=domain,dc=lab");
env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
env.put("javax.security.sasl.server.authentication", "true");
try {
DirContext ctx = new InitialDirContext(env);
// Fails here with exception as shown below
NamingEnumeration<SearchResult> _result = ctx.search("DC=domain,DC=lab","(objectClass=User)", null);
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
我得到异常
javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-03100241, problem 2001 (NO_OBJECT), data 0, best match of: 'OU=Whosebug,DC=domain,DC=lab'
请注意:该 OU 存在于 AD 系统中。
LoginCallBackHandler
的代码如下
class LoginCallBackHandler implements CallbackHandler {
@Override
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
if(callbacks != null && callbacks.length > 0) {
if(callbacks[0] instanceof NameCallback) {
((NameCallback)(callbacks[0])).setName("User@DOMAIN.LAB");
}
else if(callbacks[0] instanceof PasswordCallback) {
((PasswordCallback)(callbacks[0])).setPassword("Password".toCharArray());
}
}
}
}
我是漏掉了什么还是做错了什么?
该错误与身份验证无关。您错误地使用了 LDAP 搜索。您已经限制了搜索基础 DN ldap://XXXX.domain.lab:389/OU=Whosebug,dc=domain,dc=lab
。然后您提供了 ctx.search("DC=domain,DC=lab",...
,但没有树 DC=domain,DC=lab,OU=Whosebug,dc=domain,dc=lab
。
要么提供另一个仅具有 RootDSE 的 LDAP URL,要么向 search()
.