Package Org. JD. test; import Java. io. unsupportedencodingexception; import Java. SQL. connection; import Java. SQL. drivermanager; import Java. SQL. preparedstatement; import Java. util. hashtable; import Java. util. vector; 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. initialldapcontext; import javax. naming. LDAP. ldapcontext;/*** obtain the Organization member information of the domain in non-SSL mode * @ author gan1_**/public class adtest {/*** domain: test.jd.com * User: hhx * password: 12345678 * domain control server IP Address: 10.0.6.151 * @ Param name * @ return * @ throws unsupportedencodingexception */Public String getadinfo (string name) Throw S unsupportedencodingexception {string username = Name; // user name if (username = NULL) {username = "";} object company = ""; string host = "10.0.6.151 "; // ad server string port = "389"; // port string url = new string ("LDAP: //" + host + ":" + port ); hashtable hashenv = new hashtable (); // string adminname = "cn = oyxiaoyuanxy, Cn = users, Dc = hebmc, Dc = com "; // ad username string adminname = "test \ hhx"; // note the username format: domain \ Use Rstring adminpassword = "12345678"; // password hashenv. put (context. security_authentication, "simple"); // LDAP access security level hashenv. put (context. security_principal, adminname); // ad userhashenv. put (context. security_credentials, adminpassword); // ad passwordhashenv. put (context. initial_context_factory, "com. sun. JNDI. LDAP. ldapctxfactory "); // LDAP factory class hashenv. put (context. provider_url, URL); try {ldapcontext CTX = new Initialldapcontext (hashenv, null); // domain node string searchbase = "ou = gemdale group, Dc = test, Dc = JD, Dc = com "; // LDAP search filter class string SearchFilter = "objectclass = user"; // search controller searchcontrols searchctls = new searchcontrols (); // create the // search // controls // create search controller searchctls. setsearchscope (searchcontrols. subtree_scope); // specify // The // search // scope // set the search range // searchctls. setsearchscope (searchcontrols. object_sco PE); // specify the search scope to set the search range // string returnedatts [] = {"memberof", "distinguishedname", // "PWD-last-set ", "user-Password", "cn"}; // custom return property string returnedatts [] = {"company", "user-Password", "cn", "objectsid ", "objectguid", "Description"}; // custom returned attributes // string returnedatts [] = {"url", "whenchanged", "employeeid", // "name ", "userprincipalname", "physicaldeliveryofficename", // "Department Number "," telephonenumber "," homephone ", //" mobile "," department "," samaccountname "," whenchanged ", //" mail "}; // customize the returned property searchctls. setreturningattributes (returnedatts); // set the returned attribute set. // search for LDAP Based on the configured domain node, filter class, and search controller. The result is namingenumeration answer = CTX. search (searchbase, SearchFilter, searchctls); // search for objects using the filter // The initial search result is 0 int totalresults = 0; // specify the attributes to returnint Ro Ws = 0; while (answer. hasmoreelements () {// traverse the result set searchresult sr = (searchresult) answer. next (); // obtain the dnsystem that meets the search criteria. out. println (++ rows + "********************************* ***************"); string DN = sr. getname (); system. out. println (DN); string match = DN. split ("cn =") [1]. split (",") [0]; // The return format is generally Cn = ptyh, ou = monopoly system. out. println (MATCH); // If (username. equals (MATCH) {attributes attrs = sr. getattributes (); // Obtain the qualified property set if (attrs! = NULL) {try {for (namingenumeration Ne = attrs. getall (); ne. hasmore ();) {attribute ATTR = (attribute) NE. next (); // get the next attribute system. out. println ("attributeid = property name:" + ATTR. GETID (). tostring (); If ("objectguid ". equals (ATTR. GETID () {string ST = getguid (ATTR. get (). tostring (). getbytes (); // read the attribute value for (namingenumeration E = ATTR. getall (); E. hasmore (); totalresults ++) {// vector c = (vector) E. next (); // system. out. println (C. get (0); Company = new string (E. next (). tostring (). getbytes ("gb2312"), "UTF-8"); system. out. println ("attributevalues = property value:" + new string (company. tostring (). getbytes ("gb2312"), "UTF-8") ;}} system. out. println ("---------------") ;}} catch (namingexception e) {system. err. println ("Throw exception:" + E);} // If} // whilesystem. out. println ("************************************* ***********"); system. out. println ("number:" + totalresults); CTX. close ();} catch (namingexception e) {e. printstacktrace (); system. err. println ("Throw exception:" + E);} return company. tostring ();} Private Static string getguid (byte [] inarr) {stringbuffer guid = new stringbuffer (); For (INT I = 0; I <inarr. length; I ++) {stringbuffer dblbyte = new stringbuffer (integer. tohexstring (inarr [I] & 0xff); If (dblbyte. length () = 1) {guid. append ("0");} guid. append (dblbyte);} return guid. tostring ();} public static void main (string ARGs []) throws exception {// instantiate adtest ad = new adtest (); string Company = AD. getadinfo ("huanghx"); // class. forname ("oracle. JDBC. driver. oracledriver "); // connection conn = drivermanager. getconnection ("JDBC: oracle: thin: @ localhost: 1521: orcl", "EAS", "Kingdee"); // string SQL = "insert into ct_cos_test (FID, objectguid) values ('000000', '"+ company +"') "; // preparedstatement PS = Conn. preparestatement (SQL); // system.out.println(ps.exe cuteupdate (); // Rs. close (); // ps. close (); // Conn. close ();//}}
Supplement:
There are many examples of operating on ad through LDAP on the Internet. I also searched the company through the network and then successfullyUnknown StructureThe ad has gone through some twists and turns in the middle. Let's summarize the process below. I believe it is helpful for code farmers who need to operate the ad.
1. Notes for getting dircontext.
The following is the basic code for constructing dircontext:
Java code
- Dircontext CTX = NULL;
- String ldapurl = "LDAP: // 10.0.15.1: 389 ";
- String user = "test@xxx.com ";
- String Password = "restart #123 ";
- Hashtable Env = new hashtable ();
- Env. Put (context. initial_context_factory, "com. Sun. JNDI. LDAP. ldapctxfactory ");
- Env. Put (context. security_authentication, "simple ");
- Env. Put (context. provider_url, ldapurl );
- Env. Put (context. security_principal, user );
- Env. Put (context. security_credentials, password );
- CTX = new initialdircontext (ENV );
Dircontext CTX = NULL; string ldapurl = "LDAP: // 10.0.15.1: 389"; string user = "test@xxx.com"; string Password = "restart #123 "; hashtable Env = new hashtable (); ENV. put (context. initial_context_factory, "com. sun. JNDI. LDAP. ldapctxfactory "); ENV. put (context. security_authentication, "simple"); ENV. put (context. provider_url, ldapurl); ENV. put (context. security_principal, user); ENV. put (context. security_credentials, password); CTX = new initialdircontext (ENV );
(1) When the ad structure is unknown, ldapurl is more conservative, so no DN is added after the port.
(2) Why not use an IP address instead of a domain name, because sometimes the ad cannot be accessed through the domain name, there is instability, and the method for obtaining the domain address is as follows, enter ipconfig-all in cmd to find that the win server is both a required IP address and may have multiple IP addresses. Generally, a company with a large number of domain controllers has multiple domain controllers.
(3) User Name writing, can not directly use the user name, but to add domain information, such as userid @ domain address or domain address \ userid, such as test@xxx.com, test is a domain account, xxx.com is an ad domain name. Otherwise, an exception is reported.
2. query the notes.
Because the ad structure is unknown, the query should be conservative.
Java code
- Dircontext CNT = NULL;
- Try
- {
- CNT = This. getcontext ();
- String base = "DC = xxx, Dc = com ";
- String filter = "(& (objectclass = user) (samaccountname = * test *))";
- Int limitsize = 1;
- Searchcontrols searchcons = new searchcontrols ();
- Namingenumeration namingenum = NULL;
- Searchcons. setsearchscope (2 );
- Searchcons. setcountlimit (limitsize );
- Searchcons. settimelimit (0 );
- Namingenum = CNT. Search (base, filter, searchcons );
- Print (namingenum, base, limitsize );
- }
- Catch (exception E)
- {
- E. printstacktrace ();
- }
- Finally
- {
- If (CNT! = NULL)
- {
- CNT. Close ();
- }
- }
Dircontext CNT = NULL; try {CNT = This. getcontext (); string base = "DC = xxx, Dc = com"; string filter = "(& (objectclass = user) (samaccountname = * test *))"; int limitsize = 1; searchcontrols searchcons = new searchcontrols (); namingenumeration namingenum = NULL; searchcons. setsearchscope (2); searchcons. setcountlimit (limitsize); searchcons. settimelimit (0); namingenum = CNT. search (base, filter, searchcons ); Print (namingenum, base, limitsize);} catch (exception e) {e. printstacktrace ();} finally {If (CNT! = NULL) {CNT. Close ();}}
(1) In the case of unknown AD, the base starts to write only the DC, because the domain account is usually not directly established under the user node, and the organization is generally established by itself.
(2) The fewer filter conditions, the better, and fuzzy match is recommended, for example, string filter = samaccountname = * test * ", where test is the Logon account name.
(3) searchcons. setsearchscope (2), set to 2 to query subnodes.
(4) searchcons. settimelimit (0). If the time-out period is set to 0, there is no timeout limit.
(5) because the filtering conditions are simple and fuzzy, you can basically find the desired data, but the query will be slow if the number of nodes is large, in this case, you can add DN and Filter Based on the query result information. For example, add ou root to DN, add multiple conditions to filter, and add multiple conditions to filter (& (condition 1) (condition 2 )).
(6) The searchcons. setcountlimit (limitsize) problem. Sometimes the limitsize exception is reported during the query. This is a problem that occurs when the query result is traversed. The following is part of the traversal code:
While (namingenum! = NULL & namingenum. hasmore ())
You can manually set a limitsize. When the number of while loops reaches limitsize, The while loop exists.
(7) Disable dircontext
3. Notes for Traversing results.
(1) Processing of time
Java code
- Private string getconverttime (Object time)
- {
- Simpledateformat Sf = new simpledateformat ("yyyy-mm-dd hh: mm: SS ");
- If (time = NULL |
"". Inclusignorecase (time. tostring (). Trim ()))
- {
- Return "";
- }
- String strtime = time. tostring (). Trim ();
- If (strtime. indexof (".")! =-1)
- {
- Strtime = strtime. substring (0, strtime. indexof ("."));
- }
- Long longtime = long. valueof (strtime );
- Gregoriancalendar win32epoch = new gregoriancalendar (1601, calendar. January,
1 );
- Win32epoch. settimezone (timezone. gettimezone ("China "));
- Date win32epochdate = win32epoch. gettime ();
- Long timesincewin32epoch = longtime/
10000 + win32epochdate. gettime ();
- Date lastlogon = new date (timesincewin32epoch );
- Return SF. Format (lastlogon );
- }
Private string getconverttime (Object time) {simpledateformat Sf = new simpledateformat ("yyyy-mm-dd hh: mm: SS"); If (time = NULL | "". equalsignorecase (time. tostring (). trim () {return "";} string strtime = time. tostring (). trim (); If (strtime. indexof (". ")! =-1) {strtime = strtime. substring (0, strtime. indexof (". ");} Long longtime = long. valueof (strtime); gregoriancalendar win32epoch = new gregoriancalendar (1601, calendar. january, 1); win32epoch. settimezone (timezone. gettimezone ("China"); Date win32epochdate = win32epoch. gettime (); long timesincewin32epoch = longtime/10000 + win32epochdate. gettime (); Date lastlogon = new date (timesincewin32epoch); Return SF. format (lastlogon );}
This time is based on Greenwich Mean on January 1, January 1, 1601, and two problems need to be dealt with. A: add the Basic time of January 1, January 1, 1601-win32epochdate. gettime (), B: there is an offset between Greenwich Mean Time and your time zone (win32epoch. settimezone (timezone. gettimezone ("China "));
), So the offset to be added or subtracted is the real time.
(2) lastlogon and lastlogontimestamp, where lastlogon is updated in real time on at least one ad, while lastlogontimestamp is not updated in half a month, because lastlogon has synchronization problems on different ad, you need to find lastlogon on all the ad and find the maximum value, which is the final Logon Time.
(3) processing of the ID class. The ID attribute value is a string of binary data and needs to be converted to a string.
- Private Static string getguid (byte [] inarr)
- {
- Stringbuffer guid = new stringbuffer ();
- For (INT I =
0; I <inarr. length; I ++)
- {
- Stringbuffer dblbyte = new stringbuffer (integer. tohexstring (inarr [I] &
0xff ));
- If (dblbyte. Length () = 1)
- {
- Guid. append ("0 ");
- }
- Guid. append (dblbyte );
- }
- Return guid. tostring ();
- }