例如 memberOf出现俩次,但是search方法拿到遍历出只有一个memberOf,丢失一个
下面是一个简单的示例代码:
public static boolean authenticate(LdapContext ctx, String username, String password) {
boolean result = false;
try {
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, "uid=" + username);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(null);
result = true;
} catch (NamingException e) {
e.printStackTrace();
}
return result;
}
在这个示例中,我们使用用户提供的用户名和密码来绑定LDAP目录树上的用户对象。如果绑定成功,则返回true,否则返回false。
关于搜索用户属性出现重复的问题,可能是由于LDAP目录树中的用户对象有多个属性具有相同的名称。为了避免这种情况,可以使用Attribute.getAll()方法获取属性的所有值,而不是只使用Attribute.get()方法获取第一个值。这样可以保证获取到所有的属性值,避免丢失任何一个属性值。
下面是修改后的示例代码:
public static List<LdapUser> search(LdapContext ctx,String basedn){
List<LdapUser> lm=new ArrayList<LdapUser>();
try {
if(ctx!=null){
//过滤条件
String filter = "(objectClass=*)";
String[] attrPersonArray = { "objectClass","uid", "userPassword", "displayName", "cn", "sn", "mail", "description","objectGUID","member" };
SearchControls searchControls = new SearchControls();//搜索控件
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);//搜索范围,设为2会查询子节点。
searchControls.setDerefLinkFlag(false);
searchControls.setReturningAttributes(attrPersonArray);
NamingEnumeration<SearchResult> answer = ctx.search(basedn, filter,searchControls);
int num= 0;
while (answer.hasMore()) {
SearchResult result = (SearchResult) answer.next();
NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
LdapUser lu=new LdapUser();
while (attrs.hasMore()) {
Attribute attr = (Attribute) attrs.next();
num++;
if("uid".equals(attr.getID())){
lu.setUid(attr.get().toString());
}else if("displayName".equals(attr.getID())){
lu.setDisplayName(attr.get().toString());
}else if("cn".equals(attr.getID())){
lu.setCn(attr.get().toString());
}else if("sn".equals(attr.getID())){
lu.setSn(attr.get().toString());
}else if("memberOf".equals(attr.getID())) {
// 处理属性值出现重复的情况
NamingEnumeration<?> values = attr.getAll();
while (values.hasMore()) {
String value = values.next().toString();
if (value.startsWith("cn=")) {
lu.addMemberOf(value);
}
}
}
}
if(lu.getUid()!=null)
lm.add(lu);
}
}
}catch (Exception e) {
e.printStackTrace();
}
return lm;
}
在处理"memberOf"属性时,使用Attribute.getAll()方法获取属性的所有值,然后使用一个循环遍历每个属性值,将以"cn="开头的属性值添加到LdapUser对象的memberOf属性中。这样就可以避免丢失任何一个属性值了。
引用chatGPT作答,要校验用户的账号和密码是否正确,可以使用Bind操作。Bind操作会将用户名和密码发送到LDAP服务器进行验证,如果成功则说明用户名和密码正确。可以通过以下代码实现Bind操作:
public static boolean bind(LdapContext ctx, String username, String password, String userDn) {
boolean result = false;
try {
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(null);
result = true;
} catch (NamingException e) {
e.printStackTrace();
}
return result;
}
其中,ctx是已经连接到LDAP服务器的LdapContext对象,username是用户登录时输入的用户名,password是用户登录时输入的密码,userDn是LDAP中该用户的DN。
要解决重复属性的问题,可以通过修改返回的属性数组来处理。在这里,可以创建一个Set对象,每次遍历属性时将其添加到Set中,这样就可以去除重复属性。修改的代码如下:
public static List<LdapUser> search(LdapContext ctx,String basedn){
List<LdapUser> lm=new ArrayList<LdapUser>();
try {
if(ctx!=null){
//过滤条件
String filter = "(objectClass=*)";
String[] attrPersonArray = { "objectClass","uid", "userPassword", "displayName", "cn", "sn", "mail", "description","objectGUID","member" };
SearchControls searchControls = new SearchControls();//搜索控件
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);//搜索范围,设为2会查询子节点。
searchControls.setDerefLinkFlag(false);
searchControls.setReturningAttributes(attrPersonArray);
NamingEnumeration<SearchResult> answer = ctx.search(basedn, filter,searchControls);
int num= 0;
while (answer.hasMore()) {
SearchResult result = (SearchResult) answer.next();
NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
LdapUser lu=new LdapUser();
Set<String> memberOfs = new HashSet<>(); // 创建一个Set对象
while (attrs.hasMore()) {
Attribute attr = (Attribute) attrs.next();
num++;
if("uid".equals(attr.getID())){
lu.setUid(attr.get().toString());
}else if("displayName".equals(attr.getID())){
lu.setDisplayName(attr.get().toString());
}else if("cn".equals(attr.getID())){
lu.setCn(attr.get().toString());
}else if("sn".equals(attr.getID())){
lu.setSn(attr.get().toString());
}else if("memberOf".equals(attr.getID())){
memberOfs.add(attr.get().toString()); // 将属性添加到Set对象中
}
}
if(lu.getUid()!=null)
lm.add(lu);
if(!memberOfs.isEmpty()){ // 如果Set对象不为空,则将其转换为数组并设置到LdapUser对象中
String[] memberOfArray = memberOfs.toArray(new String[0]);
lu.setMemberOf(memberOfArray);
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
return lm;
}
用户登录验证小案例