ldap 同步用户到 ad ldap数据迁移
转载
由于业务需要,近期做了个LDAP迁移WIN AD的方案,到网上查了很多资料,发现利用java无法往AD里写入用户密码以及自定义的字段。经过咨询microsoft的工程师,得到如下结论:
1、如果要往AD写用户密码,只能通过.net或者微软提供的接口。
2、要扩展AD的自定义属性,或者元素,通过注册Schmmgmt.dll,管理AD的架构。(注册方法:开始-->运行-->cmd-->确定-->regsvr32 Schmmgmt.dll.dll)
具体操作方法如下:
一、首先定义自定义的属性(前提是已经注册好了Schmmgmt.dll.dll):
开始-->运行-->mmc-->确定
此时会弹出一个控制台,继续如下操作
文件-->添加管理单元-->Active Directory 架构-->添加-->确定
此时,展开MMC控制台最左边的的 Active Directory 架构树
右键点击属性-->新建-->属性-->继续 (以下是你自己需要的属性内容)
最后一步操作,展开类,将你新建的属性关联到类。
|
二、通过程序连接LDAP(我用的是JLDAP,当然,你可以用别的方式,网上资料很多,可以查查),伪代码如下:
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPSearchResults;
import com.novell.ldap.LDAPEntry;
String LDAP_Ip = "10.10.159.59";
int LDAP_port = 389;
LDAPConnection con = new LDAPConnection();
con.connect(LDAP_Ip , LDAP_port);
con.bind(LDAPConnection.LDAP_V3, "cn=directory manager","11111111");
LDAPSearchResults rs = con.search("ou=People,dc=test,dc=com",
LDAPConnection.SCOPE_SUB, "objectClass=*", null, false);
别忘了操作完了断开连接释放资源。
|
三、将查询到的数据写入AD(伪代码如下):
LDAPConnection con = new LDAPConnection();
con.connect("10.10.159.86", 389);
//连接AD时要注意,它的用户名为 登陆账户@域名
con.bind(LDAPConnection.LDAP_V3, "Administrator@test.com","pa$$word");
...获取LDAP的数据略
//以下是存储方法
LDAPAttributeSet attributeSet = new LDAPAttributeSet();
attributeSet.add(new LDAPAttribute("objectclass", new String("user")));
attributeSet.add(new LDAPAttribute("objectclass", new String("top")));
attributeSet.add(new LDAPAttribute("objectclass", new String("person")));
attributeSet.add(new LDAPAttribute("objectclass", new String("organizationalPerson")));
"userPrincipalName", "test"+"@test.com"));
attributeSet.add(new LDAPAttribute("samAccountName", "tesst"));
//attributeSet.add(new LDAPAttribute("datasource", "testSource"));
//attributeSet.add(new LDAPAttribute("userpassword", new String("newpassword")));
cn=test,CN=Users,DC=test,DC=com",attributeSet);
con.add(entry);
con.disconnect();
//红色部分要注意,这是不同于LDAP的地方,LDAP是UID为唯一标识,但是,AD为CN。连接完以后记得释放资源。
|
三、.net修改密码(伪代码如下):
PS:我只学了半小时.net,以前完全没接触过,写得不好,别拍砖
modifyPass.aspx
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>显示页面</title>
</head>
<body Style="padding:10px 0px 0px 0px">
<%@ import namespace="System.DirectoryServices" %>
<%@ import namespace="System.Web" %>
<%
String userName = Request.QueryString["userName"].ToString();
String passWord = Request.QueryString["passWord"].ToString();
string DomianPartA;
string DomianPartB;
string DomianName;
string DomainServerIP;
string DomianAdminName;
string DomianAdminPass;
DomianAdminName="administrator";
DomianAdminPass="Abcd1234,";
DomainServerIP="10.10.159.86";
DomianPartA="test" ;
DomianPartB="com";
DomianName= DomianPartA + "@" + DomianPartB;
//--添加用户
System.DirectoryServices.DirectoryEntry entry = new System.DirectoryServices.DirectoryEntry(DomainServer,DomianAdminName,DomianAdminPass, AuthenticationTypes.Secure);
System.DirectoryServices.DirectoryEntry subEntry = entry.Children.Find("CN=Users");
System.DirectoryServices.DirectoryEntry deUser = subEntry.Children.Find("cn="+userName);
deUser.Invoke("ChangePassword",new object[]{"",passWord});
deUser.Properties["userAccountControl"].Value = 0x200;
deUser.CommitChanges();
deUser.Close();
Response.Write("修改密码成功");
%>
</body>
</html>
|
四、java远程调用,修改密码(伪代码如下):
String id = request.getParameter("id");
String url = "http://"+ad_ip+"/modifyPass.aspx?userName="+ad+"&passWord=,Abcd1234";
HttpClient client = new HttpClient();
client.setConnectionTimeout(30 * 1000);
HttpMethod method = new GetMethod(url);
client.executeMethod(method);
if (method.getStatusLine().toString().indexOf("200") > -1) {
out.println("AD:"+method.getResponseBodyAsString()+"<br/>");
out.flush();
}
method.releaseConnection();
|
五、测试是否通过:
login_ad.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page
import="java.util.Hashtable,javax.naming.Context,javax.naming.InvalidNameException,javax.naming.NamingEnumeration,javax.naming.NamingException,javax.naming.AuthenticationException,javax.naming.directory.Attribute,javax.naming.directory.Attributes,javax.naming.directory.BasicAttribute,javax.naming.directory.BasicAttributes,javax.naming.directory.DirContext,javax.naming.directory.SearchControls,javax.naming.directory.SearchResult,javax.naming.ldap.Control,javax.naming.ldap.InitialLdapContext,javax.naming.ldap.LdapContext,javax.naming.ldap.LdapName,javax.naming.Name"%>
<%@page import="com.novell.ldap.LDAPConnection"%>
<%@page import="com.novell.ldap.LDAPSearchResults"%>
<%@page import="com.novell.ldap.LDAPEntry"%>
<%@page import="com.novell.ldap.LDAPAttribute"%>
<%@page import="com.novell.ldap.LDAPAttributeSet"%>
<%
String userName = request.getParameter("userName1");
String userPass = request.getParameter("userPass1");
LDAPConnection con = new LDAPConnection();
con.connect("10.10.159.86", 389);
//System.out.print(userName.split("\\,")[0].split("=")[1]);
con.bind(LDAPConnection.LDAP_V3, userName+"@winda.com", userPass);
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试LDAP同步AD</title>
</head>
<body>
<%
if(con != null){
out.println("登陆成功!");
}else{
out.println("登陆失败!");
}
%>
</body>
</html>
|
总结:
这只是给大家一个解决思路,此程序存在安全问题,修改密码的时候,从地址栏传参数是不允许的。可以通过.net搭建webservice的方式来解决此问题,或者是调用加密的链接。
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。