我是使用JNDI的java LDAP身份验证的新手。当我在网上寻找教程时,我从下面的URL
找到了一个示例代码。http://www.javaxt.com/Tutorials/Windows/How_to_Authenticate_Users_with_Active_Directory我正在使用JavaServlet创建web应用程序&JSP。
我只是想用LDAP认证用户。
我的服务器是Apache,Tomcat,我使用Xampp。
现在系统使用LDAP很好地验证了用户,但有时它会抛出以下异常。
" javax.naming。NamingException: Failed to connect to xxxxxx.com"
等待1小时左右,系统自动恢复正常运行
有谁能告诉我有什么问题吗?我已将服务器更改为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();
}
首先,您使用的代码抑制了真正的异常。发生的CommunicationException
是多少?根据这个代码,没办法知道。
} catch (javax.naming.CommunicationException e) {
throw new NamingException("Failed to connect to " + domainName + ((serverName == null) ? "" : " through " + serverName));
步骤1是解决这个问题,这样你至少有更多的信息,关于真正的问题是什么。
即使没有这些额外的信息,最有可能的问题是LDAP正在关闭,以便可以运行备份或重组。大多数公司运行多个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);