`
balaschen
  • 浏览: 192185 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

JNDI 连接Windows Active Directory 教程(转)

阅读更多
 
 
 
java 代码
 
  1. /***************************** LDAPFastBind.java *****************/  
  2. package test.ldap;   
  3.   
  4. import java.io.IOException;   
  5. import java.io.UnsupportedEncodingException;   
  6. import java.util.Hashtable;   
  7.   
  8. import javax.naming.AuthenticationException;   
  9. import javax.naming.Context;   
  10. import javax.naming.NamingEnumeration;   
  11. import javax.naming.NamingException;   
  12. import javax.naming.directory.Attribute;   
  13. import javax.naming.directory.Attributes;   
  14. import javax.naming.directory.BasicAttribute;   
  15. import javax.naming.directory.BasicAttributes;   
  16. import javax.naming.directory.DirContext;   
  17. import javax.naming.directory.ModificationItem;   
  18. import javax.naming.directory.SearchControls;   
  19. import javax.naming.directory.SearchResult;   
  20. import javax.naming.ldap.Control;   
  21. import javax.naming.ldap.InitialLdapContext;   
  22. import javax.naming.ldap.LdapContext;   
  23. import javax.naming.ldap.StartTlsRequest;   
  24. import javax.naming.ldap.StartTlsResponse;   
  25.   
  26. class FastBindConnectionControl implements Control {   
  27.     public byte[] getEncodedValue() {   
  28.         return null;   
  29.     }   
  30.   
  31.     public String getID() {   
  32.         return "1.2.840.113556.1.4.1781";   
  33.     }   
  34.   
  35.     public boolean isCritical() {   
  36.         return true;   
  37.     }   
  38. }   
  39.   
  40. public class LDAPFastBind {   
  41.     public Hashtable env = null;   
  42.   
  43.     public LdapContext ctx = null;   
  44.   
  45.     public Control[] connCtls = null;   
  46.   
  47.     public LDAPFastBind(String ldapurl) {   
  48.         env = new Hashtable();   
  49.         env.put(Context.INITIAL_CONTEXT_FACTORY,   
  50.                 "com.sun.jndi.ldap.LdapCtxFactory");   
  51.         env.put(Context.SECURITY_AUTHENTICATION, "simple");   
  52.         env.put(Context.PROVIDER_URL, ldapurl);   
  53.            
  54.         env.put(Context.SECURITY_PROTOCOL,"ssl");   
  55.   
  56.         String keystore = "/jdk1.5.0_09/jre/lib/security/cacerts";   
  57.         System.setProperty("javax.net.ssl.trustStore",keystore);   
  58.            
  59.         connCtls = new Control[] { new FastBindConnectionControl() };   
  60.   
  61.         // first time we initialize the context, no credentials are supplied   
  62.         // therefore it is an anonymous bind.   
  63.   
  64.         try {   
  65.             ctx = new InitialLdapContext(env, connCtls);   
  66.   
  67.         } catch (NamingException e) {   
  68.             System.out.println("Naming exception " + e);   
  69.         }   
  70.     }   
  71.   
  72.     public boolean Authenticate(String username, String password) {   
  73.         try {   
  74.             ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, username);   
  75.             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);   
  76.             ctx.reconnect(connCtls);   
  77.             System.out.println(username + " is authenticated");   
  78.             return true;   
  79.         }   
  80.   
  81.         catch (AuthenticationException e) {   
  82.             System.out.println(username + " is not authenticated");   
  83.             System.out.println(e);   
  84.             return false;   
  85.         } catch (NamingException e) {   
  86.             System.out.println(username + " is not authenticated");   
  87.             System.out.println(e);   
  88.             return false;   
  89.         }   
  90.     }   
  91.   
  92.     public void finito() {   
  93.         try {   
  94.             ctx.close();   
  95.             System.out.println("Context is closed");   
  96.         } catch (NamingException e) {   
  97.             System.out.println("Context close failure " + e);   
  98.         }   
  99.     }   
  100.   
  101.     public void printUserAccountControl() {   
  102.         try {   
  103.   
  104.             // Create the search controls   
  105.             SearchControls searchCtls = new SearchControls();   
  106.   
  107.             // Specify the search scope   
  108.             searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);   
  109.   
  110.             // specify the LDAP search filter   
  111.             //String searchFilter = "(&(objectClass=user)(CN=test))";   
  112.             //String searchFilter = "(&(objectClass=group))";   
  113.             String searchFilter = "(&(objectClass=user)(CN=peter lee))";   
  114.   
  115.             // Specify the Base for the search   
  116.             String searchBase = "DC=joeyta,DC=local";   
  117.   
  118.             // initialize counter to total the group members   
  119.             int totalResults = 0;   
  120.   
  121.             // Specify the attributes to return   
  122.             String returnedAtts[] = { "givenName""mail" };   
  123.             searchCtls.setReturningAttributes(returnedAtts);   
  124.   
  125.             // Search for objects using the filter   
  126.             NamingEnumeration answer = ctx.search(searchBase, searchFilter,   
  127.                     searchCtls);   
  128.   
  129.             // Loop through the search results   
  130.             while (answer.hasMoreElements()) {   
  131.                 SearchResult sr = (SearchResult) answer.next();   
  132.   
  133.                 System.out.println(">>>" + sr.getName());   
  134.   
  135.                 // Print out the groups   
  136.   
  137.                 Attributes attrs = sr.getAttributes();   
  138.                 if (attrs != null) {   
  139.   
  140.                     try {   
  141.                         for (NamingEnumeration ae = attrs.getAll(); ae   
  142.                                 .hasMore();) {   
  143.                             Attribute attr = (Attribute) ae.next();   
  144.                             System.out.println("Attribute: " + attr.getID());   
  145.                             for (NamingEnumeration e = attr.getAll(); e   
  146.                                     .hasMore(); totalResults++) {   
  147.   
  148.                                 System.out.println(" " + totalResults + ". "  
  149.                                         + e.next());   
  150.                             }   
  151.   
  152.                         }   
  153.   
  154.                     } catch (NamingException e) {   
  155.                         System.err.println("Problem listing membership: " + e);   
  156.                     }   
  157.   
  158.                 }   
  159.             }   
  160.   
  161.             System.out.println("Total attrs: " + totalResults);   
  162.   
  163.         }   
  164.   
  165.         catch (NamingException e) {   
  166.             System.err.println("Problem searching directory: " + e);   
  167.         }   
  168.   
  169.     }   
  170.        
  171.     public boolean adminChangePassword(String sUserName, String sNewPassword){   
  172.         try {   
  173.            
  174.             //set password is a ldap modfy operation   
  175.             ModificationItem[] mods = new ModificationItem[1];   
  176.     
  177.             //Replace the "unicdodePwd" attribute with a new value   
  178.             //Password must be both Unicode and a quoted string   
  179.             String newQuotedPassword = "\"" + sNewPassword + "\"";   
  180.             byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");   
  181.     
  182.             mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));   
  183.     
  184.             // Perform the update   
  185.             ctx.modifyAttributes(sUserName, mods);   
  186.            
  187.             System.out.println("Reset Password for: " + sUserName);       
  188.                
  189.             return true;   
  190.         }    
  191.         catch (NamingException e) {   
  192.             System.out.println("Problem resetting password: " + e);   
  193.         }   
  194.         catch (UnsupportedEncodingException e) {   
  195.             System.out.println("Problem encoding password: " + e);   
  196.         }   
  197.         return false;   
  198.     }   
  199.        
  200.     public boolean userChangePassword(String sUserName, String sOldPassword, String sNewPassword){   
  201.         try {   
  202.             //StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());   
  203.             //tls.negotiate();   
  204.                
  205.             //change password is a single ldap modify operation   
  206.             //that deletes the old password and adds the new password   
  207.             ModificationItem[] mods = new ModificationItem[2];   
  208.     
  209.             //Firstly delete the "unicdodePwd" attribute, using the old password   
  210.             //Then add the new password,Passwords must be both Unicode and a quoted string   
  211.             String oldQuotedPassword = "\"" + sOldPassword + "\"";   
  212.             byte[] oldUnicodePassword = oldQuotedPassword.getBytes("UTF-16LE");   
  213.             String newQuotedPassword = "\"" + sNewPassword + "\"";   
  214.             byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");   
  215.            
  216.             mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("unicodePwd", oldUnicodePassword));   
  217.             mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));   
  218.     
  219.             // Perform the update   
  220.             ctx.modifyAttributes(sUserName, mods);   
  221.            
  222.             System.out.println("Changed Password for: " + sUserName);       
  223.             //tls.close();   
  224.             return true;   
  225.     
  226.         }    
  227.         catch (NamingException e) {   
  228.             System.err.println("Problem changing password: " + e);   
  229.         }   
  230.         catch (UnsupportedEncodingException e) {   
  231.             System.err.println("Problem encoding password: " + e);   
  232.         } catch ( Exception e){   
  233.             System.err.println("Problem: " + e);               
  234.         }   
  235.         return false;   
  236.     }   
  237.        
  238.     public boolean createNewUser(String sGroupName, String sUserName){   
  239.         try {   
  240.             // Create attributes to be associated with the new user   
  241.             Attributes attrs = new BasicAttributes(true);    
  242.                
  243.             //These are the mandatory attributes for a user object   
  244.             //Note that Win2K3 will automagically create a random    
  245.             //samAccountName if it is not present. (Win2K does not)   
  246.             attrs.put("objectClass","user");   
  247.             attrs.put("sAMAccountName","AlanT");   
  248.             attrs.put("cn","Alan Tang");   
  249.   
  250.             //These are some optional (but useful) attributes   
  251.             attrs.put("givenName","Alan");   
  252.             attrs.put("sn","Tang");   
  253.             attrs.put("displayName","Alan Tang");   
  254.             attrs.put("description","Engineer");   
  255.             attrs.put("userPrincipalName","alan-AT-joeyta.local");   
  256.             attrs.put("mail","alang-AT-mail.joeyta-DOT-local");   
  257.             attrs.put("telephoneNumber","123 456 789");   
  258.                
  259.             //some useful constants from lmaccess.h   
  260.             int UF_ACCOUNTDISABLE = 0x0002;   
  261.             int UF_PASSWD_NOTREQD = 0x0020;   
  262.             int UF_PASSWD_CANT_CHANGE = 0x0040;   
  263.             int UF_NORMAL_ACCOUNT = 0x0200;   
  264.             int UF_DONT_EXPIRE_PASSWD = 0x10000;   
  265.             int UF_PASSWORD_EXPIRED = 0x800000;   
  266.            
  267.             //Note that you need to create the user object before you can   
  268.             //set the password. Therefore as the user is created with no    
  269.             //password, user AccountControl must be set to the following   
  270.             //otherwise the Win2K3 password filter will return error 53   
  271.             //unwilling to perform.   
  272.     
  273.             attrs.put("userAccountControl",Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED+ UF_ACCOUNTDISABLE));       
  274.            
  275.             // Create the context   
  276.             Context result = ctx.createSubcontext(sUserName, attrs);   
  277.             System.out.println("Created disabled account for: " + sUserName);   
  278.                
  279.             //now that we've created the user object, we can set the    
  280.             //password and change the userAccountControl   
  281.             //and because password can only be set using SSL/TLS   
  282.             //lets use StartTLS   
  283.     
  284.             //StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());   
  285.             //tls.negotiate();   
  286.            
  287.             //set password is a ldap modfy operation   
  288.             //and we'll update the userAccountControl   
  289.             //enabling the acount and force the user to update ther password   
  290.             //the first time they login   
  291.             ModificationItem[] mods = new ModificationItem[2];   
  292.            
  293.             //Replace the "unicdodePwd" attribute with a new value   
  294.             //Password must be both Unicode and a quoted string   
  295.             String newQuotedPassword = "\"P-AT-ssw0rd\"";   
  296.             byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");   
  297.     
  298.             mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));   
  299.             mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userAccountControl",Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWORD_EXPIRED)));   
  300.            
  301.             // Perform the update   
  302.             ctx.modifyAttributes(sUserName, mods);   
  303.             System.out.println("Set password & updated userccountControl");   
  304.     
  305.     
  306.             //now add the user to a group.   
  307.     
  308.                 try    {   
  309.                     ModificationItem member[] = new ModificationItem[1];   
  310.                     member[0]= new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", sUserName));    
  311.                    
  312.                     ctx.modifyAttributes(sGroupName,member);   
  313.                     System.out.println("Added user to group: " + sGroupName);   
  314.     
  315.                 }    
  316.                 catch (NamingException e) {   
  317.                      System.err.println("Problem adding user to group: " + e);   
  318.                 }   
  319.             //Could have put tls.close()  prior to the group modification   
  320.             //but it seems to screw up the connection  or context ?   
  321.             //tls.close();   
  322.            
  323.             System.out.println("Successfully created User: " + sUserName);   
  324.             return true;   
  325.                
  326.         }    
  327.         catch (NamingException e) {   
  328.             System.err.println("Problem creating object: " + e);   
  329.         }   
  330.        
  331.         catch (IOException e) {   
  332.             System.err.println("Problem creating object: " + e);               
  333.         }   
  334.         return false;   
  335.     }   
  336.   
  337.     public boolean addUserToGroup(LdapContext ctx, String userDN, String groupDN) {   
  338.         try{   
  339.             ModificationItem[] mods = new ModificationItem[1];   
  340.             mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", userDN));   
  341.             ctx.modifyAttributes(groupDN, mods);   
  342.             System.out.println("Added user " + userDN + " to group " + groupDN);   
  343.             return true;   
  344.         } catch (NamingException ne){   
  345.             System.err.println("Problem add user to group: " + ne);   
  346.         }   
  347.         return false;   
  348.    
分享到:
评论
1 楼 spiritfrog 2007-11-19  
userChangePassword中能否先验证OldPassword?我试了下,总是拿不到。
像你这样直接删除OldPassword,如果不存在是否会报错?

相关推荐

    java通过LDAP验证Active Directory服务

    为了通过Java实现对Active Directory的验证,我们可以使用JNDI API(Java Naming and Directory Interface),它提供了与不同目录服务(如LDAP)交互的接口。 下面是一段示例代码,展示了如何使用Java进行验证: `...

    Tomcat通过JNDI方式连接SqlServer数据库

    JNDI(Java Naming and Directory Interface)是一种Java API,用于访问命名和目录服务。在Tomcat中,我们可以使用JNDI来连接数据库。 首先,我们需要配置Tomcat来连接SqlServer数据库。我们可以在Tomcat的管理界面...

    java通过LDAP验证ActiveDirectory服务.pdf

    Active Directory是Microsoft Windows操作系统中的核心组件,用于存储和管理网络对象(如用户、计算机、组、打印机等)的目录服务。它提供了一个集中式的架构,使得管理员可以方便地控制网络资源和用户访问权限。AD...

    目录服务和+JNDI

    - **Microsoft Active Directory (AD)**:微软的企业级目录服务。 - **Sun ONE Directory Server**:Sun公司提供的目录服务。 - **Novell NDS**:Novell公司的目录服务。 **LDAP(Lightweight Directory Access ...

    com.sun.jndi.ldap.jar

    JNDI的主要作用是将Java应用程序与各种不同的命名和目录服务连接起来,如DNS、NIS、Active Directory或OpenLDAP。通过JNDI,开发者可以使用统一的API来查找、操作和管理这些服务。`com.sun.jndi.ldap.jar`中的实现...

    java使用ldap修改ad域用户密码

    在安装证书服务后,我们需要导出域根证书和计算机证书,以便使用 Java 语言连接到 Active Directory 域控制器。 使用 Keytool 工具 我们可以使用 Java 的 Keytool 工具来创建或导入证书库文件。 ```bash D:\...

    java连接AD进行用户登陆

    ### Java 连接 Active Directory 进行用户登录验证的知识点 #### 一、概述 在企业环境中,Active Directory (AD) 是一种广泛使用的目录服务,它可以帮助管理组织内的用户、设备和其他资源。对于需要集成 AD 的 ...

    JAVA JNDI免证书修改AD域密码.zip

    在IT领域,特别是Java开发中,`JAVA JNDI免证书修改AD域密码`是一个重要的主题,涉及到企业级应用与Active Directory(AD)域服务的交互。Active Directory是微软提供的目录服务,用于集中管理网络资源,如用户账户...

    java使用ldap修改ad域用户密码收集.pdf

    5、要使用 Java 修改 Active Directory 域用户密码,需要安装 Active Directory 域控制器、安装证书服务、安装 JAVA 应用程序服务器。 6、在安装证书服务的服务器中,需要导出域根证书和计算机证书,并使用 Java 的...

    数据库连接池

    - JNDI (Java Naming and Directory Interface) 不是一个专门的连接池,但它提供了一种灵活的方式来查找和管理包括数据库连接在内的各种资源。在Web应用服务器中,JNDI常被用于配置和管理数据源。 4. **BoneCP** ...

    LDAP技术,LDAP学习大全

    Windows Active Directory (AD) 是微软Windows Server操作系统中的一项关键服务,它提供了一套完整的目录服务解决方案。AD不仅实现了LDAP标准,还包含了额外的功能和服务,例如: - **集中管理**:AD允许管理员在一...

    ldap 连接 AD

    总的来说,通过理解这些源代码,你可以学习到如何在Java环境中使用LDAP协议与Active Directory进行交互,这对于构建Windows网络环境中的身份验证和授权系统至关重要。这不仅加深了对LDAP和AD的理解,也有助于提升...

    ldap 访问AD测试

    这些文件内容组合起来,形成了一套完整的使用Java通过LDAP协议与Active Directory进行交互的教程,包括了搜索、修改、验证用户、实现单点登录和证书管理等多个方面。学习这些知识点对于任何需要在企业环境中进行用户...

    java验证AD域用户登录

    AD(Active Directory)域是由微软Windows Server操作系统提供的目录服务,用于集中管理用户账户、资源权限和网络策略。在Java中实现AD域用户登录验证,主要涉及到以下知识点: 1. **JNDI (Java Naming and ...

    Ldap实例源码

    首先,源码中可能包含了使用Java LDAP API(JNDI,Java Naming and Directory Interface)来连接和操作LDAP服务器的部分。JNDI是一个接口,提供了统一的方法来访问不同的命名和目录服务,包括LDAP。通过JNDI,开发者...

    LDAP 技术总结.

    无论是 Sun One Directory Server 还是 Windows Active Directory,都是 LDAP 的具体实现,为企业信息管理和访问提供了强大支持。理解并掌握 LDAP 技术对于 IT 专业人士来说至关重要,尤其是在构建和维护跨平台的...

    集成Websphere Application Server 和Active MQ

    这可能包括创建JNDI(Java Naming and Directory Interface)上下文,定义JMS提供者,以及配置JMS目的地(如队列或主题)。 3. **设置连接工厂**: 在WAS管理控制台中,你需要创建一个JMS连接工厂,这将用于应用程序...

    DirSyncJNDI:通过使用JNDI测试DirSync

    这个项目可能是为了帮助开发者在不同目录服务之间进行数据同步,比如Active Directory和LDAP服务器。 【描述】"目录同步"是指在两个或多个目录服务之间保持数据一致性的过程。这在分布式系统和企业环境中尤其重要,...

Global site tag (gtag.js) - Google Analytics