我是使用JNDI进行Java LDAP身份验证的新手。当通过互联网搜索教程时,我发现了一个来自fallowing URL的示例代码,
http://www.javaxt.com/Tutorials/Windows/How_to_Authenticate_Users_with_Active_Directory
我正在使用JavaServlet和&amp ;;创建Web应用程序。 JSP。
我想要的是使用LDAP验证用户。
我的服务器是Apache,Tomcat,我正在使用Xampp。
现在,系统正在使用LDAP对用户进行身份验证,但有时会抛出异常情况。
" javax.naming.NamingException:无法连接到xxxxxx.com"
它会保持大约一个小时,系统会自动恢复正常。
任何人都能告诉我这是什么问题吗?
我已将服务器更改为GlassFish,但问题是相同的。
这是我的代码,
public static LdapContext getConnection (String username, String password,
String domainName, String serverName) throws NamingException {
if (domainName == null) {
try {
String fqdn = java.net.InetAddress.getLocalHost()
.getCanonicalHostName();
if (fqdn.split("\\.").length > 1) {
domainName = fqdn.substring(fqdn.indexOf(".") + 1);
}
} catch (java.net.UnknownHostException e) {
}
}
if (password != null) {
password = password.trim();
if (password.length() == 0) {
password = null;
}
}
Hashtable props = new Hashtable();
String principalName = username + "@" + domainName;
props.put(Context.SECURITY_PRINCIPAL, principalName);
if (password != null) {
props.put(Context.SECURITY_CREDENTIALS, password);
}
String ldapURL = "ldap://"
+ ((serverName == null) ? domainName : serverName + "."
+ domainName) +":389/";
String Auth_Metho="simple";
props.put(Context.SECURITY_AUTHENTICATION,
Auth_Metho);
props.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, ldapURL);
props.put("com.sun.jndi.ldap.read.timeout", "0");
try {
return new InitialLdapContext(props, null);
} catch (javax.naming.CommunicationException e) {
throw new NamingException("Failed to connect to " + domainName
+ ((serverName == null) ? "" : " through " + serverName));
} catch (NamingException e) {
throw new NamingException("Failed to authenticate " + username
+ "@" + domainName
+ ((serverName == null) ? "" : " through " + serverName));
}
}
//Then call it as....
String SreverName = "xxxxxx.com";
String userName = "xxxxx";
String password ="xxxxx";
LdapContext ctx;
try {
ctx = ActiveDirectory.getConnection( userName ,
password , SreverName);
ctx.close(); // unameStr, passStr,
System.out.println("Authenticated!");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
答案 0 :(得分:0)
首先,您使用的代码是抑制真正的异常。发生的CommunicationException
是什么?鉴于此代码,没有办法知道。
} catch (javax.naming.CommunicationException e) {
throw new NamingException("Failed to connect to " + domainName + ((serverName == null) ? "" : " through " + serverName));
第1步是解决这个问题,这样你至少可以获得有关真正问题的更多信息。
即使没有这些额外的信息,最可能的问题是LDAP被降低,以便可以运行备份或重组。大多数公司运行多个LDAP并一次关闭一个,以便可以对它们进行夜间或每周维护。解决此问题的一种方法是为PROVIDER_URL
指定多个LDAP URL,LDAP提供程序将尝试每个URL,直到成功创建连接。
props.put(Context.PROVIDER_URL, "ldap://ldap1.domain.com:389 " +
"ldap://ldap2.domain.com:389 " +
"ldap://ldap3.domain.com:389");
您可能需要与LDAP管理员联系以获取每个LDAP的URL。当您处于此状态时,请询问您的管理员何时将LDAP关闭以进行维护,并将其与您看到的连接错误相关联。
或者,如果您的公司没有针对每个单独的LDAP的DNS条目,并且您现在使用的主机名具有多个与之关联的IP地址,则可以使用InetAddress
来获取所有IP并从中构建PROVIDER_URL
。
InetAddress[] addresses = InetAddress.getAllByName(ldapHostname);
String providerUrl = "ldap://" + addresses[0].getHostAddress() + ":389";
for(int i = 1; i < addresses.length; i++){
providerUrl += " ldap://" + addresses[i].getHostAddress() + ":389";
}
props.put(Context.PROVIDER_URL, providerUrl);