使用 JAVA 将用户添加到 LDAP。 Naming.InvalidNameException: 名称无效
Add user to LDAP using JAVA. Naming.InvalidNameException: Invalid Name
我正在练习 Java,将用户添加到 LDAP(v3,运行 在我的虚拟机上)。用户详细信息和属性是从本地的 postgres 数据库 运行 获取的。
这是我的代码(可能不是一个好方法):
public class LDAPConnector {
static final String DOMAIN_URL = "ldaps://10.10.10.180:636/";
static final String ADMIN_NAME = "cn=Administrator,ou=users,dc=example,dc=com";
static final String ADMIN_PASSWORD = "password";
static final String url = "jdbc:postgresql://localhost/users";
static final String user = "username";
static final String password = "password";
static final ArrayList<String> attributeList = new ArrayList<String>();
static final Properties props = new Properties();
static DirContext ctx;
public static void main(String[] args) {
try {
props.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PRINCIPAL, ADMIN_NAME);
props.put(Context.SECURITY_CREDENTIALS, ADMIN_PASSWORD);
props.put(Context.PROVIDER_URL, DOMAIN_URL);
props.put(Context.SECURITY_PROTOCOL, "ssl");
props.put("java.naming.ldap.version", "3");
ctx = new InitialDirContext(props);
HashMap<String, String> attributeValueList = new HashMap<String, String>();
Connection con = DriverManager.getConnection(url, user, password);
Statement st = con.createStatement();
String query = "SELECT * FROM userdata";
ResultSet rs = st.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i < rsmd.getColumnCount(); i++) {
String attributeName = rsmd.getColumnName(i);
attributeList.add(attributeName);
}
while (rs.next()) {
for (int i = 0; i < attributeList.size(); i++) {
attributeValueList.put(attributeList.get(i), rs.getString(i+1));
}
}
String DN = "dn: cn="+attributeValueList.get("cn").replaceAll(" ", "")+",ou=Users"+",dc=example,dc=com";
Attribute dn = new BasicAttribute("dn",DN);
String CN = "cn: "+attributeValueList.get("cn");
Attribute cn = new BasicAttribute("cn",CN);
String SN = "sn: "+attributeValueList.get("sn");
Attribute sn = new BasicAttribute("sn",SN);
String GivenName = "givenName: "+attributeValueList.get("givenname");
Attribute givenName = new BasicAttribute("givenName",GivenName);
String ObjectClass = "objectClass: inetOrgPerson";
Attribute objectClass = new BasicAttribute("objectClass",ObjectClass);
String DisplayName = "displayName: "+attributeValueList.get("displayName");
Attribute displayName = new BasicAttribute("displayName",DisplayName);
String password = "userPassword: "+attributeValueList.get("userpassword");
Attribute userPassword = new BasicAttribute("userPassword",password);
Attributes container = new BasicAttributes();
container.put(dn);
container.put(cn);
container.put(sn);
container.put(givenName);
container.put(objectClass);
container.put(displayName);
container.put(userPassword);
String context = DN+"\r\n"+CN+"\r\n"+SN+"\r\n"+GivenName+"\r\n"+ObjectClass+"\r\n"+DisplayName+"\r\n"+password;
ctx.createSubcontext(context,container);
ctx.close();
rs.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这是我得到的异常跟踪:
javax.naming.InvalidNameException: Invalid name: dn: cn=username,ou=Users,dc=example,dc=com cn: User Name sn: User givenName: Name objectClass: inetOrgPerson displayName: user Name userPassword: Password; remaining name 'dn: cn=UserName,ou=Users,dc=example,dc=com cn: User Name sn: User givenName: Name objectClass: inetOrgPerson displayName: User Name userPassword: 123456' at
javax.naming.ldap.Rfc2253Parser.doParse(Unknown Source) at
javax.naming.ldap.Rfc2253Parser.parseDn(Unknown Source) at
javax.naming.ldap.LdapName.parse(Unknown Source) at
javax.naming.ldap.LdapName.<init>(Unknown Source) at
com.sun.jndi.ldap.LdapCtx.addRdnAttributes(Unknown Source) at
com.sun.jndi.ldap.LdapCtx.c_createSubcontext(Unknown Source) at
com.sun.jndi.toolkit.ctx.ComponentDirContext.p_createSubcontext(Unknown Source) at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.createSubcontext(Unknown Source) at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.createSubcontext(Unknown Source) at
javax.naming.directory.InitialDirContext.createSubcontext(Unknown Source) at
com.example.ldap.LDAPConnector.main(LDAPConnector.java:107)
关于如何解决异常的任何想法?我正在关注 Java JNDI tutorials
对于属性和 DN,您只需使用值(即不要在这里使用 "DN:" LDIF 语法):
String DN = "cn="+a.get("cn").replaceAll(" ","")+",ou=Users"+",dc=example,dc=com";
Attribute dn = new BasicAttribute("dn",DN);
Attribute cn = new BasicAttribute("cn",a.get("cn"));
Attribute objectClass = new BasicAttribute("objectClass", "inetOrgPerson");
...
Attributes atts = new BasicAttributes();
atts.put(dn);
atts.put(cn);
atts.put(objectClass);
ctx.createSubcontext(DN, atts);
而且我建议您从没有任何数据库访问权限的硬编码示例用户开始,直到您调试了 JNDI 使用问题,然后才更上一层楼(这也有助于询问 SO :)。
这是我的代码:除了 eckes 答案之外,引号应该在 Java 中转义,以便可以在 LDAP 中创建用户。
String DN = "\"cn="+a.get("cn").replaceAll(" ","")+",ou=Users"+",dc=example,dc=com\"";
Attribute dn = new BasicAttribute("dn",DN);
Attribute cn = new BasicAttribute("cn",a.get("cn"));
Attribute objectClass = new BasicAttribute("objectClass", "inetOrgPerson");
...
Attributes atts = new BasicAttributes();
atts.put(dn);
atts.put(cn);
atts.put(objectClass);
ctx.createSubcontext(DN, atts);
我正在练习 Java,将用户添加到 LDAP(v3,运行 在我的虚拟机上)。用户详细信息和属性是从本地的 postgres 数据库 运行 获取的。 这是我的代码(可能不是一个好方法):
public class LDAPConnector {
static final String DOMAIN_URL = "ldaps://10.10.10.180:636/";
static final String ADMIN_NAME = "cn=Administrator,ou=users,dc=example,dc=com";
static final String ADMIN_PASSWORD = "password";
static final String url = "jdbc:postgresql://localhost/users";
static final String user = "username";
static final String password = "password";
static final ArrayList<String> attributeList = new ArrayList<String>();
static final Properties props = new Properties();
static DirContext ctx;
public static void main(String[] args) {
try {
props.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PRINCIPAL, ADMIN_NAME);
props.put(Context.SECURITY_CREDENTIALS, ADMIN_PASSWORD);
props.put(Context.PROVIDER_URL, DOMAIN_URL);
props.put(Context.SECURITY_PROTOCOL, "ssl");
props.put("java.naming.ldap.version", "3");
ctx = new InitialDirContext(props);
HashMap<String, String> attributeValueList = new HashMap<String, String>();
Connection con = DriverManager.getConnection(url, user, password);
Statement st = con.createStatement();
String query = "SELECT * FROM userdata";
ResultSet rs = st.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i < rsmd.getColumnCount(); i++) {
String attributeName = rsmd.getColumnName(i);
attributeList.add(attributeName);
}
while (rs.next()) {
for (int i = 0; i < attributeList.size(); i++) {
attributeValueList.put(attributeList.get(i), rs.getString(i+1));
}
}
String DN = "dn: cn="+attributeValueList.get("cn").replaceAll(" ", "")+",ou=Users"+",dc=example,dc=com";
Attribute dn = new BasicAttribute("dn",DN);
String CN = "cn: "+attributeValueList.get("cn");
Attribute cn = new BasicAttribute("cn",CN);
String SN = "sn: "+attributeValueList.get("sn");
Attribute sn = new BasicAttribute("sn",SN);
String GivenName = "givenName: "+attributeValueList.get("givenname");
Attribute givenName = new BasicAttribute("givenName",GivenName);
String ObjectClass = "objectClass: inetOrgPerson";
Attribute objectClass = new BasicAttribute("objectClass",ObjectClass);
String DisplayName = "displayName: "+attributeValueList.get("displayName");
Attribute displayName = new BasicAttribute("displayName",DisplayName);
String password = "userPassword: "+attributeValueList.get("userpassword");
Attribute userPassword = new BasicAttribute("userPassword",password);
Attributes container = new BasicAttributes();
container.put(dn);
container.put(cn);
container.put(sn);
container.put(givenName);
container.put(objectClass);
container.put(displayName);
container.put(userPassword);
String context = DN+"\r\n"+CN+"\r\n"+SN+"\r\n"+GivenName+"\r\n"+ObjectClass+"\r\n"+DisplayName+"\r\n"+password;
ctx.createSubcontext(context,container);
ctx.close();
rs.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这是我得到的异常跟踪:
javax.naming.InvalidNameException: Invalid name: dn: cn=username,ou=Users,dc=example,dc=com cn: User Name sn: User givenName: Name objectClass: inetOrgPerson displayName: user Name userPassword: Password; remaining name 'dn: cn=UserName,ou=Users,dc=example,dc=com cn: User Name sn: User givenName: Name objectClass: inetOrgPerson displayName: User Name userPassword: 123456' at
javax.naming.ldap.Rfc2253Parser.doParse(Unknown Source) at
javax.naming.ldap.Rfc2253Parser.parseDn(Unknown Source) at
javax.naming.ldap.LdapName.parse(Unknown Source) at
javax.naming.ldap.LdapName.<init>(Unknown Source) at
com.sun.jndi.ldap.LdapCtx.addRdnAttributes(Unknown Source) at
com.sun.jndi.ldap.LdapCtx.c_createSubcontext(Unknown Source) at
com.sun.jndi.toolkit.ctx.ComponentDirContext.p_createSubcontext(Unknown Source) at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.createSubcontext(Unknown Source) at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.createSubcontext(Unknown Source) at
javax.naming.directory.InitialDirContext.createSubcontext(Unknown Source) at
com.example.ldap.LDAPConnector.main(LDAPConnector.java:107)
关于如何解决异常的任何想法?我正在关注 Java JNDI tutorials
对于属性和 DN,您只需使用值(即不要在这里使用 "DN:" LDIF 语法):
String DN = "cn="+a.get("cn").replaceAll(" ","")+",ou=Users"+",dc=example,dc=com";
Attribute dn = new BasicAttribute("dn",DN);
Attribute cn = new BasicAttribute("cn",a.get("cn"));
Attribute objectClass = new BasicAttribute("objectClass", "inetOrgPerson");
...
Attributes atts = new BasicAttributes();
atts.put(dn);
atts.put(cn);
atts.put(objectClass);
ctx.createSubcontext(DN, atts);
而且我建议您从没有任何数据库访问权限的硬编码示例用户开始,直到您调试了 JNDI 使用问题,然后才更上一层楼(这也有助于询问 SO :)。
这是我的代码:除了 eckes 答案之外,引号应该在 Java 中转义,以便可以在 LDAP 中创建用户。
String DN = "\"cn="+a.get("cn").replaceAll(" ","")+",ou=Users"+",dc=example,dc=com\"";
Attribute dn = new BasicAttribute("dn",DN);
Attribute cn = new BasicAttribute("cn",a.get("cn"));
Attribute objectClass = new BasicAttribute("objectClass", "inetOrgPerson");
...
Attributes atts = new BasicAttributes();
atts.put(dn);
atts.put(cn);
atts.put(objectClass);
ctx.createSubcontext(DN, atts);