LDAP "simple" 用户身份验证 (JNDI - 雄猫) 不稳定?



我是使用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);

最新更新