我使用以下配置配置了 OpenLDAP 服务器:
version: 1
# Entry 1: dc=unixmen,dc=com
dn: dc=unixmen,dc=com
dc: unixmen
o: unixmen
objectclass: top
objectclass: dcObject
objectclass: organization
# Entry 2: cn=ServerAdmins,dc=unixmen,dc=com
dn: cn=ServerAdmins,dc=unixmen,dc=com
cn: ServerAdmins
gidnumber: 501
objectclass: posixGroup
objectclass: top
# Entry 3: cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com
dn: cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com
cn: rcbandit
gidnumber: 501
givenname: rcbandit
homedirectory: /home/users/rcbandit
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: rcbandit
uid: rcbandit
uidnumber: 1000
userpassword: {MD5}2FeO34RYzgb7xbt2pYxcpA==
我创建了这个搜索凭据的 Java 代码:
public class SAuth
{
public static void main(String[] args)
{
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://192.168.1.177:389");
//env.put(Context.SECURITY_AUTHENTICATION, "simple");
//env.put(Context.SECURITY_PRINCIPAL, "cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com");
//env.put(Context.SECURITY_CREDENTIALS, "qwerty");
// Enable connection pooling
env.put("com.sun.jndi.ldap.connect.pool", "true");
try
{
LdapContext ctx = new InitialLdapContext(env, null);
ctx.setRequestControls(null);
NamingEnumeration<?> namingEnum = ctx.search("cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com", "(objectclass=*)", getSimpleSearchControls());
while (namingEnum.hasMore())
{
SearchResult result = (SearchResult) namingEnum.next();
Attributes attrs = result.getAttributes();
System.out.println(attrs.get("cn"));
System.out.println(attrs.get("gidnumber"));
System.out.println(attrs.get("givenname"));
System.out.println(attrs.get("homedirectory"));
System.out.println(attrs.get("objectclass"));
System.out.println(attrs.get("objectclass"));
System.out.println(attrs.get("objectclass"));
System.out.println(attrs.get("sn"));
System.out.println(attrs.get("uid"));
System.out.println(attrs.get("uidnumber"));
System.out.println(attrs.get("userpassword"));
}
namingEnum.close();
ctx.close();
}
catch (NamingException e)
{
e.printStackTrace();
}
}
private static SearchControls getSimpleSearchControls()
{
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setTimeLimit(30000);
//String[] attrIDs = {"objectGUID"};
//searchControls.setReturningAttributes(attrIDs);
return searchControls;
}
}
当我运行代码时,我得到这个结果:
cn: rcbandit
gidNumber: 501
givenName: rcbandit
homeDirectory: /home/users/rcbandit
objectClass: inetOrgPerson, posixAccount, top
objectClass: inetOrgPerson, posixAccount, top
objectClass: inetOrgPerson, posixAccount, top
sn: rcbandit
uid: rcbandit
uidNumber: 1000
null
验证用户名和密码的正确方法是什么?
最佳答案
看起来您可以通过未经身份验证的连接获取信息。但是,您需要在 LDAP 中执行 bind()
操作来执行身份验证。
The function of the Bind operation is to allow authentication information to be exchanged between the client and server. The Bind operation should be thought of as the "authenticate" operation.
更多信息here .
代码中的绑定(bind)操作将在您创建InitialLdapContext
时执行。但是,您需要拥有要验证的凭据和安全主体(您已将其注释掉)。目前您正在阅读通过未经身份验证的 channel 提供的允许信息。
正确的方法是使用实例化 InitialLdapContext
与您想要进行身份验证的主体和凭据进行绑定(bind),并捕获失败的 javax.naming.AuthenticationException
。
env.put(Context.PROVIDER_URL, "ldap://XXX.XXX.XXX.XXX:XXX");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com");
env.put(Context.SECURITY_CREDENTIALS, "xxxx");
..
LdapContext ctx = new InitialLdapContext(env, null);
}
catch(AuthenticationException ex) {
...
}
关于java - 在 LDAP 服务器中验证用户身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21064835/