`
balaschen
  • 浏览: 190182 次
  • 性别: 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,如果不存在是否会报错?

相关推荐

Global site tag (gtag.js) - Google Analytics