如何在 Java 中针对 AD 对用户进行身份验证
How to authenticate a user against AD in Java
我正在使用 JNDI 库从 Java Webapp 访问 AD。我使用技术用户通过 LDAP 对 AD 进行身份验证,如下所示:
Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT);
ldapEnv.put(Context.PROVIDER_URL, providerUrl);
ldapEnv.put(Context.SECURITY_AUTHENTICATION,
SECURITY_AUTHENTICATION_SIMPLE);
ldapEnv.put(Context.SECURITY_PRINCIPAL, principal);
ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials);
return new InitialDirContext(ldapEnv);
我用这个用户读写from/toAD.
但在那之后,我不知道如何使用他的用户名和密码来验证真正访问我的 webapp 的最终用户。
我阅读了有关使用 Context class 中的查找方法的信息,但我不确定该怎么做或如何构建搜索过滤器。例如
(&(cn= ....
我也不知道如何为广告中的所有用户查找。我想在我的网络应用程序中显示 AD
中所有可用用户的列表
为什么不对每个用户使用相同的身份验证。
见http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html
如果您获得了该用户的上下文,则意味着用户名和密码是正确的。如果没有,您将获得异常并将其发送到用户登录屏幕等。
如果通过身份验证,请不要忘记在 finally 块中关闭上下文。
我相信这 link 会拯救你的一天:
http://www.javaxt.com/Tutorials/Windows/How_to_Authenticate_Users_with_Active_Directory
您可以对用户进行身份验证并列出域的用户。
-要进行身份验证,您需要为每个尝试登录的用户创建目录上下文,就像您在问题中提到的那样。
--或者,如果您有 Weblogic 作为您的 Appserver,您可以使用 WL 容器身份验证来处理用户登录,方法是将 AD 配置为 WL 中的 authenticatoe 并保护您的登录 URL。 : 阅读更多 Configuring container-managed security in Weblogic
-列出 Root DSE 或特定 Base DN 下的所有用户
创建目录上下文以指向根 DSE 或其下的 DN
DirContext ctx = InitialDirContext(ldapEnv);
执行 context.search() 传递返回属性、搜索控件和搜索过滤器匹配用户对象 类 和登录属性
SearchControls 控件 = new SearchControls();
controls.setReturningAttributes(新字符串[]{"cn" ,"objectGUID"});
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(&(cn=*)(|(objectclass=person) (objectclass=organizationalPerson)))";
NamingEnumeration searchResult = ctx.search("", filter, controls);
-要搜索特定用户,请修改过滤器以匹配用户 cn 或任何其他属性
String filter = "(&(cn=Rafa Romero)(|(objectclass=person)(objectclass=organizationalPerson)))";
大多数 servlet 容器都可以配置为通过 LDAP 进行身份验证,这比滚动您自己的身份验证代码要安全可靠得多。
For example
-验证用户
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "LDAP://url/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "domain\user_name");
env.put(Context.SECURITY_CREDENTIALS, "password");
InitialLdapContext ctx = new InitialLdapContext(env,null);
boolean authenticated = (ctx != null) ? true : false;
-获取所有用户的名字
public ArrayList<String> getAllUsers(LdapContext ctx) {
ArrayList<String> users = new ArrayList<>();
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = {"cn"};
constraints.setReturningAttributes(attrIDs);
NamingEnumeration answer = ctx.search("dc=example,dc=com", "(&(cn=*))", constraints);
while (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
users.add(attrs.get("cn").toString().replace("cn:", ""));
}
} catch (Exception ex) {
}
return users;
}
-搜索特定用途
public String getUserName(String username, LdapContext ctx) {
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = {"cn"};
constraints.setReturningAttributes(attrIDs);
NamingEnumeration answer = ctx.search("OU=Employees,OU=Users,DC=sub_domain,DC=domain,DC=com", "uid=" + username, constraints);
if (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
return attrs.get("cn").toString().replace("cn:", "");
} else {
return null;
}
} catch (Exception ex) {
}
return null;
}
您可以从以下位置获取有关搜索查询的更多详细信息
this
我正在使用 JNDI 库从 Java Webapp 访问 AD。我使用技术用户通过 LDAP 对 AD 进行身份验证,如下所示:
Hashtable<String, String> ldapEnv = new Hashtable<String, String>(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT);
ldapEnv.put(Context.PROVIDER_URL, providerUrl);
ldapEnv.put(Context.SECURITY_AUTHENTICATION,
SECURITY_AUTHENTICATION_SIMPLE);
ldapEnv.put(Context.SECURITY_PRINCIPAL, principal);
ldapEnv.put(Context.SECURITY_CREDENTIALS, credentials);
return new InitialDirContext(ldapEnv);
我用这个用户读写from/toAD.
但在那之后,我不知道如何使用他的用户名和密码来验证真正访问我的 webapp 的最终用户。
我阅读了有关使用 Context class 中的查找方法的信息,但我不确定该怎么做或如何构建搜索过滤器。例如
(&(cn= ....
我也不知道如何为广告中的所有用户查找。我想在我的网络应用程序中显示 AD
中所有可用用户的列表为什么不对每个用户使用相同的身份验证。
见http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html
如果您获得了该用户的上下文,则意味着用户名和密码是正确的。如果没有,您将获得异常并将其发送到用户登录屏幕等。
如果通过身份验证,请不要忘记在 finally 块中关闭上下文。
我相信这 link 会拯救你的一天:
http://www.javaxt.com/Tutorials/Windows/How_to_Authenticate_Users_with_Active_Directory
您可以对用户进行身份验证并列出域的用户。
-要进行身份验证,您需要为每个尝试登录的用户创建目录上下文,就像您在问题中提到的那样。
--或者,如果您有 Weblogic 作为您的 Appserver,您可以使用 WL 容器身份验证来处理用户登录,方法是将 AD 配置为 WL 中的 authenticatoe 并保护您的登录 URL。 : 阅读更多 Configuring container-managed security in Weblogic
-列出 Root DSE 或特定 Base DN 下的所有用户
创建目录上下文以指向根 DSE 或其下的 DN
DirContext ctx = InitialDirContext(ldapEnv);
执行 context.search() 传递返回属性、搜索控件和搜索过滤器匹配用户对象 类 和登录属性
SearchControls 控件 = new SearchControls(); controls.setReturningAttributes(新字符串[]{"cn" ,"objectGUID"}); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); String filter = "(&(cn=*)(|(objectclass=person) (objectclass=organizationalPerson)))";
NamingEnumeration searchResult = ctx.search("", filter, controls);
-要搜索特定用户,请修改过滤器以匹配用户 cn 或任何其他属性
String filter = "(&(cn=Rafa Romero)(|(objectclass=person)(objectclass=organizationalPerson)))";
大多数 servlet 容器都可以配置为通过 LDAP 进行身份验证,这比滚动您自己的身份验证代码要安全可靠得多。
For example
-验证用户
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "LDAP://url/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "domain\user_name");
env.put(Context.SECURITY_CREDENTIALS, "password");
InitialLdapContext ctx = new InitialLdapContext(env,null);
boolean authenticated = (ctx != null) ? true : false;
-获取所有用户的名字
public ArrayList<String> getAllUsers(LdapContext ctx) {
ArrayList<String> users = new ArrayList<>();
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = {"cn"};
constraints.setReturningAttributes(attrIDs);
NamingEnumeration answer = ctx.search("dc=example,dc=com", "(&(cn=*))", constraints);
while (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
users.add(attrs.get("cn").toString().replace("cn:", ""));
}
} catch (Exception ex) {
}
return users;
}
-搜索特定用途
public String getUserName(String username, LdapContext ctx) {
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = {"cn"};
constraints.setReturningAttributes(attrIDs);
NamingEnumeration answer = ctx.search("OU=Employees,OU=Users,DC=sub_domain,DC=domain,DC=com", "uid=" + username, constraints);
if (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
return attrs.get("cn").toString().replace("cn:", "");
} else {
return null;
}
} catch (Exception ex) {
}
return null;
}
您可以从以下位置获取有关搜索查询的更多详细信息 this