需求:
在客户端通过javascript与java applet的交互实现Apple OS的用户和组的管理。
环境:
LDAP Sever:Apple OS Server Open Directory
JDK:6.0
Develop Tools:Eclipse 3.30
备注:
1.因为我不知道怎样修改Apple的用户密码,所以在具体应用中,用户是事先创建好的,用户名为约定的格式。在添加用户时是把可用用户的长名和短名改为用户名,在删除用户时,是把用户名的长名和短名修改回去。
2.为了方便,所有输入输出参数都为字符串类型。
3.所有过程均测试成功。
1
import java.applet.*;
2
import javax.naming.*;
3
import javax.naming.directory.*;
4
import java.util.*;
5
import javax.xml.parsers.*;
6
import org.w3c.dom.*;
7
import java.io.*;
8
import org.xml.sax.*;
9
import javax.xml.transform.*;
10
import javax.xml.transform.dom.*;
11
import javax.xml.transform.stream.*;
12
13
public 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 阅读(925)
评论(0) 编辑 收藏