LDAP 认证服务可用性监测

LDAP作为一种普遍使用的认证服务,可以通过模拟登录的方式来监测服务的可用性。今天写了一个服务来轮询模拟LDAP登录,下面是主要的代码。

LDAP的原理是先用一个admin用户去认证,认证通过后,使用应登录的用户的用户名及密码去登录。

1.常量设置

public class Constants {
 /**
 * LDAP服务端地址URL(端口默认389)
 */
public static final String ldapURL= "ldap://xxx.xxx.xxx.xxx/";
/**
 * LDAP根
 */
public static final String ldapBasedn= "ou=ldaptest,dc=ldaptest,dc=com";
/**
 * LDAP登陆账号(注:特殊字符\需要进行转义)
 */
public static final String ldapPrincipal= "ldapadmin";
/**
 * LDAP登陆密码
 */
public static final String ldapCredentials= "ldappassword";
/**
 * <B>LDAP查询Filter  <br/>#arg在代码中可替换为实际查找用户的用户账号<b/>
 */
public static final String ldapFilter= "(&(objectClass=user)(sAMAccountName=#arg))";     
}
2.LDAPAuthentication

package com.system.ldap;

import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class LDAPAuthentication implements   Runnable    {
    private final String BASEDN = Constants.ldapBasedn;
    private final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private LdapContext ctx = null;
    private final Control[] connCtls = null;
    //private Log log = null;

	public void LDAP_connect(){
		Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
        env.put(Context.PROVIDER_URL, Constants.ldapURL);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, Constants.ldapPrincipal);
        env.put(Context.SECURITY_CREDENTIALS, Constants.ldapCredentials);
        try {
        	
            ctx = new InitialLdapContext(env, connCtls);
            wirte("认证LDAP服务器(" + Constants.ldapURL + ")成功!");
        } catch (javax.naming.AuthenticationException e) {
        	wirte("认证LDAP服务器(" + Constants.ldapURL + ")失败,原因:"+e.toString());
            //throw new Exception();
        } catch (Exception e) {
        	wirte("认证LDAP服务器(" + Constants.ldapURL + ")失败,原因 :"+e.toString());
        }
	}
   
	
	public static void wirte(String msg){
		
		FileWriter fileWriter;
		try {
			
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			
			fileWriter = new FileWriter("D:\\log\\ldap.log",true);
			String s = new String( "["+sf.format(new Date())+"]"+msg);
			fileWriter.write("\r\n");
			fileWriter.write(s);  
	        fileWriter.close(); 
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
         
	}
	private String getUserDN(String uid) {
        try {
            String userDN = "";
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            // 查找用户DN
            NamingEnumeration<SearchResult> en = ctx.search(BASEDN, Constants.ldapFilter.replace("#arg", uid), constraints);
            while (en != null && en.hasMoreElements()) {
                Object obj = en.nextElement();
                if (obj instanceof SearchResult) {
                    SearchResult si = (SearchResult) obj;
                    userDN += si.getName();
                    userDN += "," + BASEDN;
                    System.out.println(userDN);
                    wirte("查找到用户" + uid + "的DN信息:" + userDN);
                } else {
                }
            }
            return userDN;
        } catch (NamingException e) {
        	wirte("查找用户DN时错误!");
        	wirte("原因:" + e);
            return null;
        } catch (Exception e1) {
            return null;
        }
    }
	public boolean authenricate(String UID, String password) {
        //是否成功
        boolean valide = false;
        try {
            //连接
            LDAP_connect(); 
            String userDN = getUserDN(UID);
            if (userDN != null && userDN != "") {
                // 如果需要加密SHA-1
                // password = SHA1.shaBase64(password);
                ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
                ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
                ctx.reconnect(connCtls);
                System.out.println(userDN + " 验证通过");
                wirte("LDAP用户验证成功!");
                valide = true;
            } else {
                wirte("未找到" + UID + "用户信息!");
                valide = false;
            }
        } catch (NamingException e) {
            wirte("用户信息认证失败!password:" + password);
            valide = false;
        } catch (Exception e) {
            //创建连接失败
            valide = false;
        } finally {
            // 关闭连接
            closeLdapContext();
            wirte("close ldap connection");
        }
        return valide;
    }
	
	private void closeLdapContext() {
        if (ctx != null) {
            try {
                ctx.close();
            } catch (NamingException e) {
            	wirte("关闭LDAP连接错误,错误原因:"+e);
            }
        }
    }
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) { 
			try {
				Thread.sleep(1000);
				LDAPAuthentication ldap = new LDAPAuthentication();
		        if (ldap.authenricate("ldapuser", "ldappassword") == true) {
		            System.out.println("该用户认证成功");
		            wirte("该用户认证成功");
		        }
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
3.测试类

使用线程轮询的方式不停地调用认证方法

public class TestLDAP {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
    	LDAPAuthentication Authentication=new LDAPAuthentication();
    	Thread t1 =new Thread(Authentication);
    	t1.start();
    }
}
4.效果

线程每轮询一次打印一次日志到文件,可以通过日志跟踪认证服务的正常状态。

5.扩展阅读

1) LDAP

http://baike.baidu.com/link?url=e59cBqJmOebBv1FnOUnDFDjAyIoLlmP2Gpg1npNF0b9FaoVO3YgAUppILHp7CPqQdDYC4w33DXxe_yIboMjb5_

2) LDAP概念和原理

http://blog.sina.com.cn/s/blog_6151984a0100ey3z.html

3)LDAP认证基本原理

http://www.edu.cn/sfrz_9956/20120608/t20120608_788018_1.shtml



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值