java访问AD备忘

注:以下文字并非全是原创,大部分是参考网上高手的资料,当时研究没有记住链接地址,代码经过改造,测试通过

1.安装虚拟机win2003
2.在win2003中按照Opad.txt中配置(须有jdk)
OpAD.java ----------------------修改密码
ADOperTest.java ----------------得到AD里用户的属性
AuthenticationTest.java --------验证用户名密码



Opad.txt:

在这就简单的介绍一下配置过程,未提到的设置基本就都采用默认即可。

1)安装AD:
开始 -> 运行 -> dcpromote ,应该是dcpromo
域名: testad.com.cn
NT域名: ldap
即 Fully Qualified Domain Name (FQDN) 为 ldap.testad.com.cn
注意,一定要先安装 IIS , 再安装 CA.
2)安装 IIS:
开始-> 程序 -> 管理工具 -> 配置您的服务器向导 -> 应用服务器 (IIS, ASP.NET)
进入 http:// ldap.testad.com.cn /iisstart.htm 表示安装成功.
3)安装CA:
开始-> 设置 -> 控制面板-> 添加或删除程序 ->添加/删除Windows组件 -> 证书服务
选择 企业根CA
共用名称 CA: testca
进入 http:// ldap.testad.com.cn /CertSrv 表示安装成功.
4)生成证书请求:
开始->程序->管理工具-> Internet 信息服务 (IIS) 管理器 -> Internet信息服务-> (本地计算机) -> 网站
-> 右键点选 默认网站 -> 属性 ->选择 "目录安全性" -> 服务器证书
->新建证书 -> 准备证书,但稍后发送
公共名称最好设置为 ldap.testad.com.cn, 这是给使用者连ssl 的 站点.
最后产生证书请求文件 , 默认为c:\certreq.txt
5)在CA上请求证书:
进入 http:// ldap.testad.com.cn /CertSrv
按 申请一个证书 -> 高级证书申请
-> 使用 base64 编码的 CMC 或 PKCS #10 文件提交一个证书申请,或使用 base64 编码的 PKCS #7 文件续订证书申请。
使用 记事本 打开 c:\certreq.txt , copy c:\certreq.txt 内容贴至 保存的申请:
证书模板 选择 Web 服务器, 按 提交
然后点选 下载证书 , 将 certnew.cer 储存至 c:\certnew.cer
6)安装证书:
开始->程序->管理工具-> Internet 信息服务 (IIS) 管理器 -> Internet信息服务-> (本地计算机) -> 网站
-> 右键点选默认网站->属性 -> 选择 "目录安全性" ->服务器证书
->处理挂起的请求,安装证书 -> 路径和文件名: c:\certnew.cer
网站SSL 端口: 443
7)将 CA 证书 加入至keystore 里:
进入 http:// ldap.testad.com.cn /CertSrv
点选 下载一个 CA 证书,证书链或 CRL
点选 下载 CA 证书, 然后下载并改名为 c:\ca_cert.cer
安装CA后LDAP服务器C盘根目录会生成一文件ldap.testad.com.cn_testca.crt
然后执行 命令:
keytool -import -keystore "c:/testca.keystore" -file "ldap.testad.com.cn_testca.crt" -storepass "changeit"
keytool -import -keystore "c:/testca.keystore" -alias mkey -file "c:/ca_cert.cer" -storepass "changeit"
出现 Trusted this certificate? 按 "y" 即新增成功.

但经过个人的测试,其实只需使用ldap.testad.com.cn_testca.crt这个证书就可以连接上SSL AD 636。


OpAD.java

package com.dj.ad.test;

import java.io.UnsupportedEncodingException;
import java.util.Hashtable;

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.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class OpAD {

private LdapContext ctx = null;

private String adminName = "administrator@demo.com";

private String adminpassword = "nhm2010";

private String keystore = "C:/testca.keystore";

private String keyPassword = "123456";

private String ldapURL = "ldaps://192.168.1.29:636";

private String searchBase = "DC=demo,DC=com";

private String returnedAtts[] = { "distinguishedName" };

/**
* 初始化
*
* @return
*/
private boolean initial_Ldap() {

Hashtable env = new Hashtable();
System.setProperty("javax.net.ssl.trustStore", keystore);
System.setProperty("javax.net.ssl.trustStorePassword", keyPassword);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, adminName);
env.put(Context.SECURITY_CREDENTIALS, adminpassword);
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.PROVIDER_URL, ldapURL);

try {
System.out.println("Start InitialLdapContext");
ctx = new InitialLdapContext(env, null);
System.out.println("InitialLdapContext succeed");
} catch (NamingException e) {
System.out.println("Problem initial_Ldap NamingException: " + e);
return false;
}

return true;
}

private boolean close_Ldap() {
System.out.println("Close Ldap");
try {
ctx.close();
} catch (NamingException e) {
System.out.println("Problem close_Ldap NamingException: " + e);
return false;
}
return true;
}

/**
* 搜索用户
*
* @param username
* @return
*/
private String search_distinguishedName(String username) {
String searchFilter = "(&(objectClass=user)(cn=" + username + "))";

try {
System.out.println("Start search " + username
+ "'s distinguishedName");
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchCtls.setReturningAttributes(returnedAtts);
NamingEnumeration answer = ctx.search(searchBase, searchFilter,
searchCtls);
if (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
Attributes attrs = sr.getAttributes();
if (attrs != null) {
NamingEnumeration ae = attrs.getAll();
Attribute attr = (Attribute) ae.next();
NamingEnumeration e = attr.getAll();
return (String) e.next();
}
}
} catch (NamingException e) {
System.out
.println("Problem search_distinguishedName NamingException: "
+ e);
return "error";
}

return "none";
}

/**
* 修改密码
*
* @param username
* @param password
* @return
*/
private boolean mod_Pwd(String username, String password) {
ModificationItem[] mods = new ModificationItem[1];
String newQuotedPassword = "\"" + password + "\"";

try {
System.out.println("Start reset password");
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("unicodePwd", newUnicodePassword));
ctx.modifyAttributes(username, mods);
System.out.println("Finish reset password" + username);
} catch (UnsupportedEncodingException e) {
System.out.println("Problem mod_Pwd UnsupportedEncodingException: "
+ e);
return false;
} catch (NamingException e) {
System.out.println("Problem mod_Pwd NamingException: " + e);
return false;
}

return true;
}

public static void main(String args[]) {
OpAD inst = new OpAD();
inst.initial_Ldap();
String username = inst.search_distinguishedName("oyxiaoyuanxy");
System.out.println(username);
inst.mod_Pwd(username, "snewpsd");
inst.close_Ldap();

}

}


ADOperTest.java

package com.dj.ad.test;

import java.util.Hashtable;

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;

public class ADOperTest {

public ADOperTest() {

}

public void GetADInfo() {
Hashtable HashEnv = new Hashtable();

String LDAP_URL = "ldap://192.168.1.29:389"; // LDAP访问地址
// String adminName ="CN=oyxiaoyuanxy,CN=Users,DC=Hebmc,DC=com";//AD的用户名
String adminName = "demo\\oyxy"; // 注意用户名的写法:domain\User 或 User@domain.com
adminName = "oyxy@demo.com"; // 注意用户名的写法:domain\User 或 User@domain.com
String adminPassword = "xiaoyuan"; // 密码

HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
HashEnv.put(Context.SECURITY_PRINCIPAL, adminName); // AD User
HashEnv.put(Context.SECURITY_CREDENTIALS, adminPassword); // AD
// Password
HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
HashEnv.put(Context.PROVIDER_URL, LDAP_URL);

try {
LdapContext ctx = new InitialLdapContext(HashEnv, null);

// 域节点
String searchBase = "DC=demo,DC=com"; // Specify the Base for the search

// LDAP搜索过滤器类
String searchFilter = "objectClass=User"; // specify the LDAP search filter
// String searchFilter = "objectClass=organizationalUnit";//specify the LDAP search filter

// 搜索控制器
SearchControls searchCtls = new SearchControls(); // Create the search controls 创建搜索控制器
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Specify the search scope 设置搜索范围
// searchCtls.setSearchScope(SearchControls.OBJECT_SCOPE); // Specify the search scope 设置搜索范围
String returnedAtts[] = {"memberOf","distinguishedName","Pwd-Last-Set","User-Password","cn"};//定制返回属性
// String returnedAtts[] = { "url", "whenChanged", "employeeID",
// "name", "userPrincipalName", "physicalDeliveryOfficeName",
// "departmentNumber", "telephoneNumber", "homePhone",
// "mobile", "department", "sAMAccountName", "whenChanged",
// "mail" }; // 定制返回属性
searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集

//根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
NamingEnumeration answer = ctx.search(searchBase, searchFilter,
searchCtls);// Search for objects using the filter

//初始化搜索结果数为0
int totalResults = 0;// Specify the attributes to return
int rows=0;

while (answer.hasMoreElements()) {//遍历结果集
SearchResult sr = (SearchResult) answer.next();//得到符合搜索条件的DN
System.out.println(++rows+"************************************************");
System.out.println(sr.getName());
Attributes Attrs = sr.getAttributes();//得到符合条件的属性集
if (Attrs != null) {
try {
for (NamingEnumeration ne = Attrs.getAll(); ne
.hasMore();) {
Attribute Attr = (Attribute) ne.next();//得到下一个属性
System.out.println(" AttributeID=属性名:"+ Attr.getID().toString());
// 读取属性值
for (NamingEnumeration e = Attr.getAll(); e
.hasMore(); totalResults++) {
System.out.println(" AttributeValues=属性值:"+ e.next().toString());
}
System.out.println(" ---------------");
// 读取属性值
// Enumeration values = Attr.getAll();
// if (values != null) { // 迭代
// while (values.hasMoreElements()) {
//System.out.println(" AttributeValues=属性值:"+ values.nextElement());
// }
// }
//System.out.println(" ---------------");
}
} catch (NamingException e) {
System.err.println("Throw Exception : " + e);
}
}
}
System.out.println("************************************************");
System.out.println("Number: " + totalResults);
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
System.err.println("Throw Exception : " + e);
}
}

public static void main(String args[]) {
ADOperTest ad = new ADOperTest();
ad.GetADInfo();
}
}

ADConnection.java

package com.dj.ad.test;

import java.security.Security;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

/**
* java 代码操作MS AD实现单点登录
*
* @author
*
*/
public class ADConnection {

DirContext ldapContext;
String baseName = ",cn=users,DC=demo,DC=com";
String serverIP = "192.168.1.29";
String modelUsername = "oyxiaoyuanxy";

public ADConnection() {
try {
Hashtable ldapEnv = new Hashtable(11);
ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
ldapEnv.put(Context.PROVIDER_URL, "ldaps://" + serverIP + ":636");
// ldapEnv.put(Context.PROVIDER_URL, "ldap://" + serverIP
// + ":389/dc=demo,dc=com");
ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=administrator"
+ baseName);
ldapEnv.put(Context.SECURITY_CREDENTIALS, "nhm2010");
ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
ldapContext = new InitialDirContext(ldapEnv);
} catch (Exception e) {
System.out.println(" bind error: " + e);
e.printStackTrace();
System.exit(-1);
}
}

public void createNew(String username, String surname, String givenName) {
try {
String distinguishedName = "cn=" + username + baseName;
Attributes newAttributes = new BasicAttributes(true);
Attribute oc = new BasicAttribute("objectclass");
oc.add("top");
oc.add("person");
oc.add("organizationalperson");
oc.add("user");
newAttributes.put(oc);
newAttributes.put(new BasicAttribute("sAMAccountName", username));

/**
* 密码
*/
String quotedPassword = "\"xiaoyuan\"";
byte[] newUnicodePassword = quotedPassword.getBytes("UTF-16LE");
newAttributes.put(new BasicAttribute("unicodePwd",
newUnicodePassword));

/**
* 账户权限值,密码设置将失效,默认为空
*/
int UF_ACCOUNTDISABLE = 0x0001;
int UF_PASSWD_NOTREQD = 0x0010;
int UF_NORMAL_ACCOUNT = 0x0200;
// int UF_PASSWORD_EXPIRED = 0x800000;
String str = Integer.toString(UF_NORMAL_ACCOUNT
+ UF_PASSWD_NOTREQD
// + UF_PASSWORD_EXPIRED
+ UF_ACCOUNTDISABLE);
newAttributes.put("userAccountControl", str);

newAttributes.put(new BasicAttribute("userPrincipalName", username
+ "@" + serverIP));
newAttributes.put(new BasicAttribute("cn", username));
newAttributes.put(new BasicAttribute("sn", surname));
newAttributes.put(new BasicAttribute("givenName", givenName));
newAttributes.put(new BasicAttribute("displayName", givenName + " "
+ surname));
System.out.println("Name: " + distinguishedName + " Attributes: "
+ newAttributes);
ldapContext.createSubcontext(distinguishedName, newAttributes);
} catch (Exception e) {
System.out.println("create error: " + e);
e.printStackTrace();
System.exit(-1);
}
}

/**
* 克隆一个用户
*
* @param username
* @param surname
* @param givenName
*/
public void createClone(String username, String surname, String givenName) {
try {
Attributes modelAttributes = fetch(modelUsername);
System.out.println("createClone:");
String distinguishedName = "cn=" + username + baseName;
Attributes newAttributes = new BasicAttributes(true);
newAttributes.put(modelAttributes.get("objectclass"));
// newAttributes.put(modelAttributes.get("userAccountControl"));
int UF_ACCOUNTDISABLE = 0x0002;
int UF_PASSWD_NOTREQD = 0x0020;
int UF_PASSWD_CANT_CHANGE = 0x0040;
int UF_NORMAL_ACCOUNT = 0x0200;
int UF_DONT_EXPIRE_PASSWD = 0x10000;
int UF_PASSWORD_EXPIRED = 0x800000;
String str = Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD
+ UF_PASSWORD_EXPIRED + UF_ACCOUNTDISABLE);
newAttributes.put("userAccountControl", str);
// newAttributes.put("userpassword", "\"xiaoyuan\"");
newAttributes.put("sAMAccountName", username);
newAttributes.put("userPrincipalName", username + "@" + serverIP);
newAttributes.put("cn", username);
newAttributes.put("sn", surname);
newAttributes.put("givenName", givenName);
newAttributes.put("displayName", givenName + " " + surname);
System.out.println("distinguishedName: " + distinguishedName
+ "\n Attributes: \n" + newAttributes);
ldapContext.createSubcontext(distinguishedName, newAttributes);
} catch (Exception e) {
System.err.println("创建出错:\n " + e);
e.printStackTrace();
System.exit(-1);
}
}

public void update(String username) {
try {
System.out.println("updating...\n");
ModificationItem[] mods = new ModificationItem[1];
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("description", "java y"));
ldapContext.modifyAttributes("cn=" + username + baseName, mods);
} catch (Exception e) {
System.out.println(" update error: " + e);
System.exit(-1);
}
}

public void updatePassword(String username, String password) {
try {
System.out.println("updating password...\n");
String quotedPassword = "\"" + password + "\"";
/*
* char unicodePwd[] = quotedPassword.toCharArray(); byte pwdArray[] =
* new byte[unicodePwd.length * 2]; for (int i = 0; i <
* unicodePwd.length; i++) { pwdArray[i * 2 + 1] = (byte)
* (unicodePwd[i] >>> 8); pwdArray[i * 2 + 0] = (byte)
* (unicodePwd[i] & 0xff); } System.out.print("encoded password: ");
* for (int i = 0; i < pwdArray.length; i++) {
* System.out.print(pwdArray[i] + " "); } System.out.println();
* ModificationItem[] mods = new ModificationItem[1]; mods[0] = new
* ModificationItem(DirContext.REPLACE_ATTRIBUTE, new
* BasicAttribute("UnicodePwd", pwdArray));
* ldapContext.modifyAttributes("cn=" + username + baseName, mods);
*/
ModificationItem[] mods = new ModificationItem[1];
byte[] newUnicodePassword = quotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("unicodePwd", newUnicodePassword));
ldapContext.modifyAttributes("cn=" + username + baseName, mods);

} catch (Exception e) {
System.err.println("修改密码出错:\n " + e);
System.exit(-1);
}
}

/**
* 查找用户属性
*
* @param username
* @return
*/
public Attributes fetch(String username) {
Attributes attributes = null;
String userDN = getUserDN(username);
System.out.println("得到DN:" + userDN);
try {
System.out.println("fetching: " + username);
DirContext o = (DirContext) ldapContext.lookup(userDN);
System.out.println("search done\n");
attributes = o.getAttributes("");
System.out.println("************************");
for (NamingEnumeration ae = attributes.getAll(); ae
.hasMoreElements();) {
Attribute attr = (Attribute) ae.next();
String attrId = attr.getID();
for (NamingEnumeration vals = attr.getAll(); vals.hasMore();) {
String thing = vals.next().toString();
System.out.println(attrId + ": " + thing);
}
}
System.out.println("************************");
} catch (Exception e) {
System.out.println(" fetch error: " + e);
System.exit(-1);
}
return attributes;
}

/**
* 根据ID得到用户在LDAP中的完整DN
*
* @param userid
* @return
*/
private String getUserDN(String userid) {
System.out.println("getUserDN:" + userid);
String userDN = "";
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String filter = "(&(objectClass=user)(CN=" + userid + "))";
NamingEnumeration en = ldapContext.search("dc=demo,dc=com", filter,
constraints);
if (en == null) {
System.out.println("Have NO such user!");
}
if (!en.hasMoreElements()) {
System.out.println("Have NO such user!");
}
while (en != null && en.hasMoreElements()) {
Object obj = en.nextElement();
if (obj instanceof SearchResult) {
SearchResult si = (SearchResult) obj;
userDN += si.getName();
userDN += "," + "dc=demo,dc=com";
} else {
System.out.println(obj);
}
}
} catch (Exception e) {
System.out.println("Exception in search user DN : " + e.toString());
}
return userDN;
}

public static void main(String[] args) {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// the keystore that holds trusted root certificates
System.setProperty("javax.net.ssl.trustStore",
"C:/Java/jdk1.6.0_12/bin/testca.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "123456");
// System.setProperty("javax.net.debug", "all");
ADConnection adc = new ADConnection();
// adc.createClone("clone1", "Clone", "Clarissa");
// adc.updatePassword("clone1", "xiaoyuan");
adc.createNew("user1", "User", "Joe");
// Attributes a = adc.fetch("clone1");
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值