Windows Server 2008 Active Directory 安装及使用笔记

1.安装AD

http://www.docin.com/p-191729140.html

问题

安装 windows server 2008企业版,安装完后administrator密码为空,随后自己设置了符合密码策略的密码。服务器已经重启过。但在建AD时,确切说运行dcpromo后,提示administrator账号密码不符合要求,进行不下去。

解决方法:使用administrator登录系统,cmd运行如下命令:

C:\Users\Administrator>net user administrator /passwordreq:yes

命令成功完成。

安装VPN服务,开启AD后可以使用AD中配置的账号登录。

http://ce.sysu.edu.cn/hope2008/Education/ShowArticle.asp?ArticleID=8913

 

2.密码复杂度限制

http://www.cnblogs.com/ceachy/articles/2418657.html

 

以下步骤是为了实现java+ldap修改密码

3.安装证书服务

服务器管理器--角色--添加角色

http://blog.sina.com.cn/s/blog_67288bc90100jbwh.html

http://wenku.baidu.com/link?url=NGj3ZlGIBK3NQxXqFIgKDqGKelGz7EYhoyxpFcI5OrNpCG6li37TeAIPdVdXcmGN_ClX7LC7LtVpSml-fwjpBAgIX5qP5zeKCfGBE9oWYMO

 

4.向mmc中添加证书管理器

http://technet.microsoft.com/zh-cn/library/aa997890(EXCHG.80).aspx

 

5.java使用ldap修改用户密码

简单说就是三步:

1)通过mmc导出3中生成的ca证书

2)新建一个“个人”证书,类型为“域控制器身份验证”,并将其导出

3)将导出的两个证书使用java的keytool 分别导入到xx.keystore中

http://wenku.baidu.com/view/e30d73bcc77da26925c5b0c8.html

 

亲测,只导入1)中的证书就可以连接ssl了,将生成的security.keystore保存到指定路径即可。

keytool -import -alias local-ad-server -file "ad_server.cer"  -keystore "security.keystore"   -storepass changeit

6.cas+ldap

http://www.micmiu.com/enterprise-app/sso/sso-cas-ldap-auth/

 

7.通过IIS修改密码

windows server 2003 :http://wenku.baidu.com/view/00994454f01dc281e53af043.html

windows server 2008 :http://wenku.baidu.com/view/0698385fbe23482fb4da4c43.html

 

8.其它

LDAP百度百科:http://baike.baidu.com/view/159263.htm

AD常用命令:http://wenku.baidu.com/view/7196dc1fc281e53a5802ffcf.html

 

 

LdapUtil.java

package utils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

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.BasicAttributes;
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 LdapUtil {


	public static LdapContext ctxTDS;

	/**
	 * 连接LDAP
	 */
	public static LdapContext connetLDAP() throws NamingException {
		// 连接Ldap需要的信息
		if (ctxTDS == null) {
			String ldapFactory = "com.sun.jndi.ldap.LdapCtxFactory";
			String ldapUrl = "ldaps://169.254.105.76:636";// url,如果是ssl协议,端口是636
			String ldapAccount = "CN=Administrator,CN=Users,DC=piaoyi,DC=local"; // 用户名
			String ldapPwd = "LdapAdminPassword";// 密码
			Hashtable<String, String> env = new Hashtable<String, String>();
			env.put(Context.INITIAL_CONTEXT_FACTORY, ldapFactory);
			// LDAP server
			env.put(Context.PROVIDER_URL, ldapUrl);
			env.put(Context.SECURITY_AUTHENTICATION, "simple");
			env.put(Context.SECURITY_PRINCIPAL, ldapAccount);
			env.put(Context.SECURITY_CREDENTIALS, ldapPwd);
			env.put(Context.REFERRAL, "follow");

			// ssl证书
			String keystore = "D:/ldap_modify/security.keystore";// 证书路径:cacerts文件路径
			System.setProperty("javax.net.ssl.trustStore", keystore);
			System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
			env.put(Context.SECURITY_PROTOCOL, "ssl");

			ctxTDS = new InitialLdapContext(env, null);
			System.out.println("##########Connet LDAP success!##########");
		}
		return ctxTDS;
	}

	/**
	 * 查询用户是否存在
	 * 
	 * @param propertityName
	 * @param propertityValue
	 * @return
	 */
	public static List<String> searchDNByPropertity(String propertityName,
			String propertityValue) {
		System.out.println("##########search LDAP start!##########");
		List<String> list = new ArrayList<String>();
		String userDN = "";
		LdapContext ctx;
		try {
			ctx = connetLDAP();
			String filter = "(&(objectClass=top)(objectClass=organizationalPerson)("
					+ propertityName + "=" + propertityValue + "))";
			// 限制要查询的字段内容
			String[] attrPersonArray = { "distinguishedName" };
			SearchControls searchControls = new SearchControls();
			searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
			// 设置将被返回的Attribute
			searchControls.setReturningAttributes(attrPersonArray);
			// 三个参数分别为:
			// 上下文;
			// 要搜索的属性,如果为空或 null,则返回目标上下文中的所有对象;
			// 控制搜索的搜索控件,如果为 null,则使用默认的搜索控件
			NamingEnumeration<SearchResult> answer = ctx.search(
					"DC=piaoyi,DC=local", filter.toString(),
					searchControls);
			// 输出查到的数据
			while (answer.hasMore()) {
				SearchResult result = answer.next();
				NamingEnumeration<? extends Attribute> attrs = result
						.getAttributes().getAll();
				while (attrs.hasMore()) {
					Attribute attr = attrs.next();
					userDN = (String) attr.get();
					list.add(userDN);
					System.out.println(attr.getID() + "=" + attr.get());
				}
			}
			System.out.println("##########search LDAP success!##########");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("##########search LDAP fail!##########");
		}
		// 设置过滤条件

		return list;
	}

	/**
	 * 修改用户属性,这种方式不能修改用户密码
	 * 
	 * @param userDN
	 * @param map
	 * @return
	 */
	public static boolean ModifyPropertiesByDN(String userDN,
			Map<String, String> map) {
		System.out.println("##########Data modify start!##########");
		boolean result = true;
		LdapContext ctx;
		try {
			ctx = connetLDAP();
			Attributes attrs = new BasicAttributes(true);
			for (Map.Entry<String, String> entry : map.entrySet()) {

				attrs.put(entry.getKey(), entry.getValue());

				System.out.println("Key = " + entry.getKey() + ", Value = "
						+ entry.getValue());

			}

			ctx.modifyAttributes(userDN, DirContext.REPLACE_ATTRIBUTE, attrs);
			System.out.println("##########Data modify success!##########");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			result = false;
			e.printStackTrace();
			System.out.println("##########Data modify fail!##########");
		}

		return result;

	}

	/**
	 * 删除用户
	 * 
	 * @param userDN
	 * @return
	 */
	public static boolean RemoveUserByDN(String userDN) {
		System.out.println("##########Data remove start!##########");
		boolean result = true;
		LdapContext ctx;
		try {
			ctx = connetLDAP();
			ctx.destroySubcontext(userDN);
			System.out.println("##########Data remove success!##########");
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			result = false;
			e.printStackTrace();
			System.out.println("##########Data remove fail!##########");
		}

		return result;

	}

	/**
	 * 添加用户
	 * 
	 * javax.naming.OperationNotSupportedException: [LDAP: error code 53 -
	 * 0000052D: SvcErr: DSID-031A0FC0, problem 5003 (WILL_NOT_PERFORM), data 0]
	 * 
	 * 异常原因:密码不符合密码策略。 解决方式两种:1、把密码改得复杂点,大小写+数字+字母等等。 2、把AD密码策略去掉。
	 * 
	 * javax.naming.OperationNotSupportedException: [LDAP: error code 53 -
	 * 0000001F: SvcErr: DSID-031A0FC0, problem 5003 (WILL_NOT_PERFORM), data 0]
	 * 
	 * 异常原因:必须使用证书才可修改AD密码。【注意:和上边的异常只差在 error code 后边的一长串码上,一定要看清楚了】
	 * 解决方式:配置成SSL证书形式。先创建用户,再修改密码。
	 * 
	 * @param userDN
	 * @param cn
	 * @param password
	 * @param map
	 * @return
	 */
	public static boolean AddUserByMap(String userDN, String cn,
			String password, Map<String, String> map) {
		System.out.println("##########Data add start!##########");
		boolean result = true;
		LdapContext ctx;
		try {
			ctx = connetLDAP();

			List<String> list = searchDNByPropertity("distinguishedName",
					userDN);
			if (list == null || list.size() == 0) {

				Attributes attrs = new BasicAttributes(true);
				Attribute objclass = new BasicAttribute("objectclass");
				// 添加ObjectClass
				String[] attrObjectClassPerson = { "user",
						"organizationalPerson", "person", "top" };
				Arrays.sort(attrObjectClassPerson);
				for (String ocp : attrObjectClassPerson) {
					objclass.add(ocp);
				}
				attrs.put(objclass);

				attrs.put("cn", cn);

				for (Map.Entry<String, String> entry : map.entrySet()) {
					attrs.put(entry.getKey(), entry.getValue());
					System.out.println("Key = " + entry.getKey() + ", Value = "
							+ entry.getValue());

				}
				ctx.createSubcontext(userDN, attrs);
				System.out.println("##########Data add success!##########");

				if (password != null && !"".equals(password)) {
					modifyUserPasswordByDN(userDN, password);
				}

			} else {
				result = false;
				System.out.println("##########Data has exist!##########");
			}
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			result = false;
			e.printStackTrace();
			System.out.println("##########Data add fail!##########");
		}
		return result;

	}

	/**
	 * 修改指定用户的密码
	 * 
	 * @param userDN
	 * @param password
	 * @return
	 */
	public static boolean modifyUserPasswordByDN(String userDN, String password) {
		System.out.println("##########Modify password start!##########");
		boolean result = true;
		LdapContext ctx;
		try {
			ctx = connetLDAP();
			ModificationItem[] mods = new ModificationItem[1];
			String newQuotedPassword = "\"" + password + "\"";
			byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
			mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
					new BasicAttribute("unicodePwd", newUnicodePassword));
			ctx.modifyAttributes(userDN, mods);
			System.out.println("##########Modify password success!##########");
		} catch (NamingException | UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			result = false;
			e.printStackTrace();
			System.out.println("##########Modify password fail!##########");
		}

		return result;
	}

}

 

 

 

 

猜你喜欢

转载自hanqunfeng.iteye.com/blog/1835046