package com.ejweb.conf;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
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;
import java.util.Hashtable;

public class LDAPUtil {  
      
    private String url;  
    private String basedn;  
    private String domain;  
    private String userdn;  
    private String userPassword;  
    private Hashtable<String, String> env = new Hashtable<String, String>(); 
    private LdapContext ctx = null;  
    private Control[] connCtls = null;
    
    public LDAPUtil(){
//        url = PropertyManager.getValue("url");  
//        basedn = PropertyManager.getValue("basedn");  
//        domain=PropertyManager.getValue("domain");  
    	url = GConstants.getValue("url");
    	basedn = GConstants.getValue("basedn");
    	userdn= GConstants.getValue("userdn");
    	userPassword= GConstants.getValue("userPassword");
    }  
    //链接LDAP服务器
    public  void connectLdap() {  
           boolean result=false;  
//           LdapContext ldapContext = null;  
           //用户名称，cn,ou,dc 分别：用户，组，域  
//           env.put(Context.SECURITY_PRINCIPAL, userName);  
           env.put(Context.SECURITY_PRINCIPAL, userdn);  
           //用户密码 cn 的密码  
//           env.put(Context.SECURITY_CREDENTIALS, passwd);  
           env.put(Context.SECURITY_CREDENTIALS, userPassword);  
           //url 格式：协议://ip:端口/组,域   ,直接连接到域或者组上面  
//           env.put(Context.PROVIDER_URL, url+basedn);  
           env.put(Context.PROVIDER_URL, url);  
           //LDAP 工厂  
           env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");  
           //验证的类型     "none", "simple", "strong"  
           env.put(Context.SECURITY_AUTHENTICATION, "simple");  
           try {  
        	   ctx = new InitialLdapContext(env, connCtls);  
            result=true;  
            System.out.println("---Ldap 链接成功----");  
        } catch (NamingException e) {  
            //e.printStackTrace();  
            System.out.println("--- get connection failure ----");  
        }  
           
    }  
    /** 
     * 关闭ldap 
     */  
    public void closeLdap(){  
        try {  
            this.ctx.close();  
        } catch (NamingException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
    } 
    
    //获取用户信息  
    public String GetUserInfo(String uid,String attibute) {
        String company = "";
        try {  
            // 域节点  
//            String searchBase = "DC=xx,DC=xxx,DC=com";  
            String searchBase = basedn;  
            // LDAP搜索过滤器类  
            //cn=*name*模糊查询 cn=name 精确查询  
//          String searchFilter = "(objectClass="+type+")";  
//            String searchFilter = "(&(objectClass="+type+")("+filter+"=*" + name + "*))"; 
//            String searchFilter = "(&(objectClass=Users)(uid=刘满江))";

//            String searchFilter = "cn=刘满江";
            String searchFilter = "uid="+uid;
            // 创建搜索控制器  
            SearchControls searchCtls = new SearchControls();   
            //  设置搜索范围  
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);   
            String returnedAtts[] = {attibute}; // 定制返回属性
            searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集 不设置则返回所有属性  
            // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果  
            NamingEnumeration answer = ctx.search(searchBase, searchFilter,searchCtls);// Search for objects using the filter  
            
            // 初始化搜索结果数为0  
            int totalResults = 0;// Specify the attributes to return  
            int rows = 0;  
            while (answer.hasMoreElements()) {// 遍历结果集  
                SearchResult sr = (SearchResult) answer.next();// 得到符合搜索条件的DN  
                ++rows;  
                String dn = sr.getName();  
                System.out.println(dn);  
                Attributes Attrs = sr.getAttributes();// 得到符合条件的属性集  
                if (Attrs != null) {  
                    try {  
                        for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore();) {  
                            Attribute Attr = (Attribute) ne.next();// 得到下一个属性  
                            System.out.println(" AttributeID=属性名："+ Attr.getID().toString());  
                            // 读取属性值  
                            for (NamingEnumeration e = Attr.getAll(); e.hasMore(); totalResults++) {  
                                company = e.next().toString();  
                                System.out.println("    AttributeValues=属性值："+ company);  
                            }  
                            System.out.println("    ---------------");  
  
                        }  
                    } catch (NamingException e) {  
                        System.err.println("Throw Exception : " + e);  
                    }  
                }// if  
            }// while  
            System.out.println("************************************************");  
            System.out.println("Number: " + totalResults);  
            System.out.println("总共用户数："+rows);  
        } catch (NamingException e) {  
            e.printStackTrace();  
            System.err.println("Throw Exception : " + e);  
        }  
        return company;
    }  
    
    
    public String getUserDN(String uid){
        String userDN = "";
        
        try{
               SearchControls constraints = new SearchControls();
               constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
               NamingEnumeration en = ctx.search("", "uid="+uid, constraints); //The UID you are going to query,* means all nodes
               if(en == null){
                System.out.println("Have no NamingEnumeration.");
               }
               if(!en.hasMoreElements()){
                System.out.println("Have no element.");
               }
               while (en != null && en.hasMoreElements()){//maybe more than one element
                   Object obj = en.nextElement();
                   if(obj instanceof SearchResult){
                       SearchResult si = (SearchResult) obj;
                       userDN += si.getName();
//                       userDN += "," + basedn;
                   }
                   else{
                       System.out.println(obj);
                   }
                   System.out.println(userDN);
               }
              }catch(Exception e){
               System.out.println("Exception in search():"+e);
              }
        
        return userDN;
    }
    //根据用户名、密码，验证用户是否正确
    public boolean authenricate(String ID,String password){
        boolean valide = false;
        String userDN = getUserDN(ID);
//        String userDN = "uid=LIUMANJIANG,cn=Users,dc=sunac,dc=com,dc=cn";
        try {
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL,userDN);
            ctx.addToEnvironment(Context.SECURITY_CREDENTIALS,password);
            ctx.reconnect(connCtls);
            System.out.println(userDN + " is authenticated");
            valide = true;
        }catch (AuthenticationException e) {
            System.out.println(userDN + " is not authenticated");
            System.out.println(e.toString());
            valide = false;
        }catch (NamingException e) {
            System.out.println(userDN + " is not authenticated");
            valide = false;
        }
        
        return valide;
    }
    
    public static void main(String[] args) {  
        LDAPUtil util=new LDAPUtil();
        /* 
         * uid=qsk1,ou=People,dc=jt-test,dc=com 
         */
        util.connectLdap();//链接IDM
        //验证用户是否正确
//        boolean validate = util.authenricate("LIUMANJIANG1","Abcd1234");
        //        boolean validate = util.authenricate("zhaozhirong","asdf1234");
        boolean validate = util.authenricate("qianlijiao","111111");
        if(validate){
        	String orgName = util.GetUserInfo("LIUMANJIANG1","ORGDISPLAYNAME");//获取用户组织
        }
        
        util.closeLdap();
    }  
} 