需求:
在客户端通过javascript与java applet的交互实现Apple OS的用户和组的管理。
环境:
LDAP Sever:Apple OS Server Open Directory
JDK:6.0
Develop Tools:Eclipse 3.30
备注:
1.因为我不知道怎样修改Apple的用户密码,所以在具体应用中,用户是事先创建好的,用户名为约定的格式。在添加用户时是把可用用户的长名和短名改为用户名,在删除用户时,是把用户名的长名和短名修改回去。
2.为了方便,所有输入输出参数都为字符串类型。
3.所有过程均测试成功。
1import java.applet.*;
2import javax.naming.*;
3import javax.naming.directory.*;
4import java.util.*;
5import javax.xml.parsers.*;
6import org.w3c.dom.*;
7import java.io.*;
8import org.xml.sax.*;
9import javax.xml.transform.*;
10import javax.xml.transform.dom.*;
11import javax.xml.transform.stream.*;
12
13public class LdapUtil extends Applet{
14 /** *//**
15 * 把XML格式字符串转换为Document
16 * @param xml XML格式字符串
17 * @return
18 * @throws Exception
19 */
20 private Document lodaXmlString(String xml) throws Exception{
21 DocumentBuilder docBuilder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
22
23 StringReader strReader=new StringReader(xml);
24 InputSource inSrc=new InputSource(strReader);
25
26 Document xmlDoc=docBuilder.parse(inSrc);
27
28 return xmlDoc;
29 }
30
31 /** *//**
32 * 把Document转换为XML格式字符串
33 * @param xmlDoc Document
34 * @return String
35 * @throws Exception
36 */
37 private String xmlDocumentToString(Document xmlDoc) throws Exception{
38 DOMSource domSource=new DOMSource(xmlDoc);
39 StringWriter writer=new StringWriter();
40 StreamResult result=new StreamResult(writer);
41 TransformerFactory tf=TransformerFactory.newInstance();
42 Transformer transformer=tf.newTransformer();
43 transformer.transform(domSource, result);
44
45 return writer.toString();
46 }
47
48 /** *//**
49 * 读取XML格式配置信息转换为DieContext
50 * @param env XML格式配置信息
51 * @return
52 * @throws Exception
53 */
54 private DirContext connect(String env) throws Exception{
55 Element root=this.lodaXmlString(env).getDocumentElement();
56 NodeList nodeList=root.getChildNodes();
57
58 int length=nodeList.getLength();
59
60 Properties pro=new Properties();
61
62 for(int i=0;i<length;i++){
63 Node node=nodeList.item(i);
64
65 if(node.getNodeName()=="factory"){
66 pro.put(Context.INITIAL_CONTEXT_FACTORY, node.getTextContent());
67 }
68 else if(node.getNodeName()=="providerURL"){
69 pro.put(Context.PROVIDER_URL, node.getTextContent());
70 }
71 else if(node.getNodeName()=="principal"){
72 pro.put(Context.SECURITY_PRINCIPAL, node.getTextContent());
73 }
74 else if(node.getNodeName()=="authentication"){
75 pro.put(Context.SECURITY_AUTHENTICATION, node.getTextContent());
76 }
77 else if(node.getNodeName()=="credentials"){
78 pro.put(Context.SECURITY_CREDENTIALS, node.getTextContent());
79 }
80 else if(node.getNodeName()=="version"){
81 pro.put("java.naming.ldap.version", node.getTextContent());
82 }
83
84 }
85
86 return new InitialDirContext(pro);
87 }
88
89 /** *//**
90 * 报XML字符串转换为SearchControls
91 * @param ctr
92 * @return SearchControls
93 * @throws Exception
94 */
95 private SearchControls parseXmlToSearchControls(String ctr) throws Exception{
96 Element root=this.lodaXmlString(ctr).getDocumentElement();
97
98 NodeList nodeList=root.getChildNodes();
99
100 int length=nodeList.getLength();
101
102 SearchControls sc=new SearchControls();
103
104 for(int i=0;i<length;i++){
105 Node node=nodeList.item(i);
106
107 if(node.getNodeName()=="countLimit"){
108 sc.setCountLimit(Long.parseLong(node.getTextContent()));
109 }
110 else if(node.getNodeName()=="derefLinkFlag"){
111 sc.setDerefLinkFlag(Boolean.parseBoolean(node.getTextContent()));
112 }
113 else if(node.getNodeName()=="returningAttributes"){
114 sc.setReturningAttributes(node.getTextContent().split(","));
115 }
116 else if(node.getNodeName()=="returningObjFlag"){
117 sc.setReturningObjFlag(Boolean.parseBoolean(node.getTextContent()));
118 }
119 else if(node.getNodeName()=="searchScope"){
120 sc.setSearchScope(Integer.parseInt(node.getTextContent()));
121 }
122 else if(node.getNodeName()=="searchScope"){
123 sc.setSearchScope(Integer.parseInt(node.getTextContent()));
124 }
125 else if(node.getNodeName()=="timeLimit"){
126 sc.setTimeLimit(Integer.parseInt(node.getTextContent()));
127 }
128 }
129
130 return sc;
131 }
132
133 /** *//**
134 * 查找
135 * @param env XML格式LDAP配置信息
136 * @param name 查找的节点名称
137 * @param filter 属性过滤条件
138 * @param ctr XML格式的SearchControls信息
139 * @return
140 */
141 public String search(String env,String name,String filter,String ctr){
142 DirContext ctx=null;
143 SearchControls sc=new SearchControls();
144 NamingEnumeration<SearchResult> rs=null;
145 String result="";
146
147 try{
148 ctx=this.connect(env);
149 if(ctr!=null && ctr!=""){
150 sc=this.parseXmlToSearchControls(ctr);
151 }
152
153 rs=ctx.search(name,filter,sc);
154
155 DocumentBuilder docBuilder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
156
157 Document xmlDoc=docBuilder.newDocument();
158
159 Element rootEl=xmlDoc.createElement("searchResult");
160
161 while(rs!=null && rs.hasMore()){
162 SearchResult el=rs.next();
163 String elName=el.getName();
164 NamingEnumeration<? extends Attribute> attrs=el.getAttributes().getAll();
165
166 Element recordEl=xmlDoc.createElement("record");
167
168 recordEl.setAttribute("name", elName);
169
170 while(attrs!=null && attrs.hasMore()){
171 Attribute attr=attrs.next();
172 NamingEnumeration<?> attrEnu=attr.getAll();
173 String attrName=attr.getID();
174
175 while(attrEnu!=null && attrEnu.hasMore()){
176 Object o=attrEnu.next();
177 Element attrEl=xmlDoc.createElement("attribute");
178
179 attrEl.setAttribute("name",attrName);
180 attrEl.setTextContent(o.toString());
181
182 recordEl.appendChild(attrEl);
183 }
184 }
185
186 rootEl.appendChild(recordEl);
187 }
188
189 ctx.close();
190
191 xmlDoc.appendChild(rootEl);
192
193 result=xmlDocumentToString(xmlDoc);
194 }
195 catch(Exception ex){
196 ex.printStackTrace();
197 }
198
199 return result;
200 }
201
202 /** *//**
203 * 添加用户
204 * 没有真正添加
205 * 是把可用的用户的长名和短名修改为指定的用户名
206 * @param env XML格式LDAP配置信息
207 * @param format 可用用户名格式
208 * @param name 用户名称
209 * @return
210 */
211 public String addUser(String env,String format,String name){
212 DirContext ctx=null;
213 String result="false";
214
215 try{
216 SearchControls sctr=new SearchControls();
217
218 sctr.setSearchScope(2);
219 sctr.setReturningAttributes(new String[]{"sn","cn"});
220
221 ctx=this.connect(env);
222 NamingEnumeration<SearchResult> rs=ctx.search("cn=users","cn="+format+"*",sctr);
223
224 String usableName="";
225
226 while(rs!=null && rs.hasMore()){
227 SearchResult el=rs.nextElement();
228
229 if(el.getAttributes().get("sn").get(0).toString().startsWith(format)){
230 usableName=el.getName();
231
232 break;
233 }
234 }
235
236 if(usableName==""){
237 throw new Exception("没有可用用户资源");
238 }
239
240 ModificationItem[] mods=new ModificationItem[2];
241
242 mods[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
243 new BasicAttribute("sn", name));
244 mods[1]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
245 new BasicAttribute("cn", name));
246
247 ctx.modifyAttributes(usableName+",cn=users", mods);
248
249 ctx.close();
250
251 result="true";
252 }
253 catch(Exception ex){
254 ex.printStackTrace();
255 result="false";
256 }
257
258 return result;
259 }
260
261 /** *//**
262 * 把用户添加到指定组
263 * @param env XML格式LDAP配置信息
264 * @param groupName 组名称
265 * @param userName 用户名称
266 * @return
267 */
268 public String addUserToGroup(String env,String groupName,String userName){
269 DirContext ctx=null;
270 String result="";
271
272 try{
273 SearchControls sctr=new SearchControls();
274
275 sctr.setSearchScope(2);
276 sctr.setReturningAttributes(new String[]{"uid","apple-generateduid","sn","cn"});
277
278 ctx=this.connect(env);
279 NamingEnumeration<SearchResult> rs=ctx.search("cn=users","cn="+userName,sctr);
280
281 String uid="";
282 String userGuid="";
283 String dn="";
284
285 while(rs!=null && rs.hasMore()){
286 SearchResult el=rs.nextElement();
287 Attribute attrCn=el.getAttributes().get("cn");
288 Attribute attrUid=el.getAttributes().get("uid");
289 Attribute attrUserGuid=el.getAttributes().get("apple-generateduid");
290
291 if(attrCn.get(0).toString().trim().equalsIgnoreCase(userName)){
292 uid=attrUid.get(0).toString();
293 userGuid=attrUserGuid.get(0).toString();
294 dn=el.getName();
295
296 break;
297 }
298 }
299
300 if(dn==""){
301 throw new Exception("没有找到此用户");
302 }
303
304 ModificationItem[] mods=new ModificationItem[2];
305
306 mods[0]=new ModificationItem(DirContext.ADD_ATTRIBUTE,
307 new BasicAttribute("memberUid",uid));
308 mods[1]=new ModificationItem(DirContext.ADD_ATTRIBUTE,
309 new BasicAttribute("apple-group-memberguid",userGuid));
310
311 ctx.modifyAttributes("cn="+groupName+",cn=groups", mods);
312
313 result="true";
314
315 ctx.close();
316 }
317 catch(Exception ex){
318 ex.printStackTrace();
319 result="false";
320 }
321
322 return result;
323 }
324
325 /** *//**
326 * 从组中删除用户
327 * @param env XML格式LDAP配置信息
328 * @param groupName 组名称
329 * @param uid 用户ID
330 * @return
331 */
332 public String deleteGroupUser(String env,String groupName,String uid){
333 DirContext ctx=null;
334 String result="";
335
336 try{
337 SearchControls sctr=new SearchControls();
338
339 sctr.setSearchScope(2);
340 sctr.setReturningAttributes(new String[]{"apple-generateduid"});
341
342 ctx=this.connect(env);
343 NamingEnumeration<SearchResult> rs=ctx.search("cn=users","uid="+uid,sctr);
344
345 String userGuid="";
346
347 while(rs!=null && rs.hasMore()){
348 SearchResult el=rs.nextElement();
349 userGuid=el.getAttributes().get("apple-generateduid").get(0).toString();
350 }
351
352 ModificationItem[] mods=new ModificationItem[2];
353
354 mods[0]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
355 new BasicAttribute("memberUid",uid));
356 mods[1]=new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
357 new BasicAttribute("apple-group-memberguid",userGuid));
358
359 ctx.modifyAttributes("cn="+groupName+",cn=groups", mods);
360
361 ctx.close();
362
363 result="true";
364 }
365 catch(Exception ex){
366 ex.printStackTrace();
367 result="false";
368 }
369
370 return result;
371 }
372
373 /** *//**
374 * 删除用户
375 * 没有真正删除用户
376 * 是把用户的长名和短名改为可用格式
377 * @param env XML格式LDAP配置信息
378 * @param format 可用用户名的格式
379 * @param name 用户名称
380 * @return
381 */
382 public String deleteUser(String env,String format,String name){
383 DirContext ctx=null;
384 String result="";
385
386 try{
387 SearchControls sctr=new SearchControls();
388
389 sctr.setSearchScope(2);
390 sctr.setReturningAttributes(new String[]{"uid"});
391
392 ctx=this.connect(env);
393 NamingEnumeration<SearchResult> rs=ctx.search("cn=users","cn="+name,sctr);
394
395 String dn="";
396
397 while(rs!=null && rs.hasMore()){
398 dn=rs.nextElement().getName();
399
400 break;
401 }
402
403 if(dn==""){
404 throw new Exception("没有找到此用户");
405 }
406
407 String dnName=dn.replace("uid=", "").trim();
408
409 ModificationItem[] mods=new ModificationItem[2];
410
411 mods[0]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
412 new BasicAttribute("sn", dnName));
413 mods[1]=new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
414 new BasicAttribute("cn", dnName));
415
416 ctx.modifyAttributes(dn+",cn=users", mods);
417
418 result="true";
419
420 ctx.close();
421 }
422 catch(Exception ex){
423 ex.printStackTrace();
424 result="false";
425 }
426
427 return result;
428 }
429
430 /** *//**
431 * 获取指定组的用户
432 * @param env XML格式LDAP配置信息
433 * @param groupName 组名
434 * @param ctr XML格式SearchControls
435 * @return
436 */
437 public String getGroupUsers(String env,String groupName,String ctr){
438 DirContext ctx=null;
439 String result="";
440
441 try{
442 SearchControls sctr=new SearchControls();
443
444 sctr.setSearchScope(2);
445 sctr.setReturningAttributes(new String[]{"memberUid"});
446
447 ctx=this.connect(env);
448 NamingEnumeration<SearchResult> rs=ctx.search("cn=groups","cn="+groupName,sctr);
449
450 ArrayList<String> uids=new ArrayList<String>();
451
452 while(rs!=null && rs.hasMore()){
453 SearchResult el=rs.nextElement();
454 Attribute attrUids=el.getAttributes().get("memberUid");
455
456 NamingEnumeration<?> nAttrUids=attrUids.getAll();
457
458 while(nAttrUids!=null && nAttrUids.hasMore()){
459 Object uid=nAttrUids.nextElement();
460
461 uids.add(uid.toString());
462 }
463 }
464
465 int uidsSize=uids.size();
466
467 if(uidsSize>0){
468 sctr=null;
469 sctr=this.parseXmlToSearchControls(ctr);
470 DocumentBuilder docBuilder=DocumentBuilderFactory.newInstance().newDocumentBuilder();
471
472 Document xmlDoc=docBuilder.newDocument();
473
474 Element rootEl=xmlDoc.createElement("searchResult");
475
476 for(int i=0;i<uidsSize;i++){
477 rs=null;
478 rs=ctx.search("cn=users", "uid="+uids.get(i),sctr);
479
480 while(rs!=null && rs.hasMore()){
481 SearchResult el=rs.nextElement();
482 String elName=el.getName();
483 NamingEnumeration<? extends Attribute> attrs=el.getAttributes().getAll();
484
485 Element recordEl=xmlDoc.createElement("record");
486
487 recordEl.setAttribute("name", elName);
488
489 while(attrs!=null && attrs.hasMore()){
490 Attribute attr=attrs.next();
491 NamingEnumeration<?> attrEnu=attr.getAll();
492 String attrName=attr.getID();
493
494 while(attrEnu!=null && attrEnu.hasMore()){
495 Object o=attrEnu.next();
496 Element attrEl=xmlDoc.createElement("attribute");
497
498 attrEl.setAttribute("name",attrName);
499 attrEl.setTextContent(o.toString());
500
501 recordEl.appendChild(attrEl);
502 }
503 }
504
505 rootEl.appendChild(recordEl);
506 }
507 }
508
509 xmlDoc.appendChild(rootEl);
510
511 result=xmlDocumentToString(xmlDoc);
512 }
513 }
514 catch(Exception ex){
515 ex.printStackTrace();
516 result="false";
517 }
518
519 return result;
520 }
521
522 /** *//**
523 * 删除组
524 * @param env XML格式LDAP配置信息
525 * @param name 组名
526 * @return
527 */
528 public String deleteGroup(String env,String name){
529 DirContext ctx=null;
530 String result="";
531
532 try{
533 ctx=this.connect(env);
534
535 ctx.destroySubcontext("cn="+name+",cn=groups");
536
537 ctx.close();
538
539 result="true";
540 }
541 catch(Exception ex){
542 ex.printStackTrace();
543 result="false";
544 }
545
546 return result;
547 }
548
549 /** *//**
550 * 添加组
551 * @param env XML格式LDAP配置信息
552 * @param name 组名称
553 * @return
554 */
555 public String addGroup(String env,String name){
556 DirContext ctx=null;
557 String result="false";
558
559 try{
560 int gidNumber=this.getMaxGeneratedNumber(env,"groups","gidNumber");
561
562 if(gidNumber>0){
563 BasicAttributes battrs=new BasicAttributes();
564 BasicAttribute battr= new BasicAttribute("objectClass");
565
566 battr.add("posixGroup");
567 battr.add("apple-group");
568 battr.add("extensibleObject");
569
570 battrs.put(battr);
571 battrs.put("gidNumber",String.valueOf(gidNumber));
572 battrs.put("cn",name);
573 battrs.put("apple-group-realname",name);
574 battrs.put("apple-generateduid",java.util.UUID.randomUUID().toString().toUpperCase());
575
576 ctx=this.connect(env);
577
578 ctx.createSubcontext("cn="+name+",cn=groups",battrs);
579
580 ctx.close();
581
582 result="true";
583 }
584 }
585 catch(Exception ex){
586 ex.printStackTrace();
587 result="false";
588 }
589
590 return result;
591 }
592
593 /** *//**
594 * 返回自动生成ID的可用数字
595 * @param env XML格式LDAP配置信息
596 * @param cn 查找的节点
597 * @param genAttr 自动生成ID的属性名称
598 * @return
599 */
600 public int getMaxGeneratedNumber(String env,String cn,String genAttr){
601 DirContext ctx=null;
602 int maxGen=0;
603
604 try{
605 SearchControls sctr=new SearchControls();
606
607 sctr.setSearchScope(2);
608 sctr.setReturningAttributes(new String[]{genAttr});
609
610 ctx=this.connect(env);
611 NamingEnumeration<SearchResult> rs=ctx.search("cn="+cn,genAttr+"=*",sctr);
612
613 while(rs!=null && rs.hasMore()){
614 SearchResult el=rs.nextElement();
615 Attribute attr=el.getAttributes().get(genAttr);
616
617 int genNumber=Integer.parseInt(attr.get(0).toString());
618
619 if(maxGen<genNumber){
620 maxGen=genNumber;
621 }
622 }
623
624 ctx.close();
625 }
626 catch(Exception ex){
627 ex.printStackTrace();
628 maxGen=0;
629 }
630
631 return maxGen;
632 }
633}
634
具体代码:
posted on 2007-08-17 12:52
Terry Liang 阅读(923)
评论(0) 编辑 收藏