我正在开发一个小型系统来控制我工作和学习的大学的计算机实验室。用户将使用其域用户登录系统。集成本身正在运行,我已经能够检索用户的一些信息,例如他们所属的组,他们的名字和其他东西(下面代码的更多信息)。但我想要做的事情就像戴尔的SonicWall那样。用户使用他的AD帐户访问SonicWall,他们所属的群组允许他们访问某些网站。
我也希望通过AD组控制访问级别,为此我需要仅检索系统的某些组以验证用户应具有的权限。
这是关于系统的简要说明。这就是我尝试做的事情:使用AD群组为用户提供某些权限,但我无法只检索以labinfo_
开头的群组。下面是我到目前为止的代码。
我的主要课程,我正在使用make test。
import java.io.*;
import java.util.*;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchResult;
public class ActiveDirectoryTest {
public static void main(String[] args) throws NamingException, IOException {
try {
String domain = "umc.br";
String ch = "username";
String user, pwd, search;
Console console = System.console();
Scanner scan = new Scanner(System.in);
System.out.print("Usuário: ");
user = scan.next();
pwd = String.valueOf(console.readPassword("Senha: "));
System.out.print("Termo de busca: ");
search = scan.next();
ActiveDirectory activeDirectory = new ActiveDirectory(user, pwd, domain);
NamingEnumeration<SearchResult> result = activeDirectory.searchUser(search, ch, null);
if (result.hasMore()) {
SearchResult rs = (SearchResult) result.next();
Attributes attrs = rs.getAttributes();
String cn = attrs.get("cn").toString();
System.out.println("Nome completo: " + cn.substring(cn.indexOf(":") + 1));
String samaccountname = attrs.get("samaccountname").toString();
System.out.println("Usuário: " + samaccountname.substring(samaccountname.indexOf(":") + 1));
String groups = attrs.get("memberOf").toString();
System.out.println("Grupo: " + groups);
if (attrs.get("mail") == null) {
System.out.println("Email: não cadastrado");
} else {
String mail = attrs.get("mail").toString();
System.out.println("Email: " + mail.substring(mail.indexOf(":") + 1));
}
} else {
System.out.println("Resultado não encontrado!");
}
activeDirectory.closeLdapConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
}
我在互联网上找到的一个ActiveDirectory类,使用预先制作的方法向我提供有关用户的信息。
import java.util.Properties;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
public class ActiveDirectory {
private static final Logger LOG = Logger.getLogger(ActiveDirectory.class.getName());
private Properties properties;
private DirContext dirContext;
private SearchControls searchCtls;
private String[] returnAttributes = {"sAMAccountName", "givenName", "cn", "mail", "memberOf"};
private String domainBase;
private String baseFilter = "(&((&(objectCategory=Person)(objectClass=User)))";
public ActiveDirectory(String username, String password, String domainController) {
properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
properties.put(Context.PROVIDER_URL, "LDAP://" + domainController);
properties.put(Context.SECURITY_PRINCIPAL, username + "@" + domainController);
properties.put(Context.SECURITY_CREDENTIALS, password);
try {
dirContext = new InitialDirContext(properties);
} catch (NamingException e) {
LOG.severe(e.getMessage());
}
domainBase = getDomainBase(domainController);
searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchCtls.setReturningAttributes(returnAttributes);
}
public NamingEnumeration<SearchResult> searchUser(String searchValue, String searchBy, String searchBase) throws NamingException {
String filter = getFilter(searchValue, searchBy);
String base = (null == searchBase) ? domainBase : getDomainBase(searchBase);
return this.dirContext.search(base, filter, this.searchCtls);
}
public void closeLdapConnection() {
try {
if (dirContext != null) {
dirContext.close();
}
} catch (NamingException e) {
LOG.severe(e.getMessage());
}
}
private String getFilter(String searchValue, String searchBy) {
String filter = this.baseFilter;
if (searchBy.equals("email")) {
filter += "(mail=" + searchValue + "))";
} else if (searchBy.equals("username")) {
filter += "(samaccountname=" + searchValue + "))";
}
return filter;
}
private static String getDomainBase(String base) {
char[] namePair = base.toUpperCase().toCharArray();
String dn = "DC=";
for (int i = 0; i < namePair.length; i++) {
if (namePair[i] == '.') {
dn += ",DC=" + namePair[++i];
} else {
dn += namePair[i];
}
}
return dn;
}
}
编辑:我更改了LDAP查询以查看是否可行。嗯,异常改变了,哈哈。现在它给了我javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name 'DC=UMC,DC=BR'
。
当前的LDAP查询为(&((&(objectClass=group)(name=labinfo_*))&(objectCategory=Person)(objectClass=User))(samaccountname=" + searchValue + "))
。
EDIT2:我现在将LDAP查询更改为(&(&(objectCategory=person)(objectClass=user))(&(objectCategory=group)(sAMAccountName=labinfo_*))(sAMAccountName=" + searchValue + "))
,但我一直收到同样的错误。
答案 0 :(得分:0)
我设法通过查询(&(objectClass=user)(memberOf=CN=" + group + ",OU=FIFTH_OU,OU=FOURTH_OU,OU=THIRD_OU,OU=SECOND,OU=FIRST_OU,DC=umc,DC=br)(sAMAccountName=" + searchValue + "))"
仅返回我想要的群组。我必须为该组提供整个路径,包括所有OU和DC。它让我困扰了很长时间,但它终于奏效了。