域控制器(Active Directory)
Windows AD(Active Direcotry),域控制器是指在“域”模式下,至少有一台服务器负责每一台联入网络的电脑和用户的验证工作,相当于一个单位的门卫一样,称为“域控制器(Domain Controller,简写为DC)”。
域控制器中包含:域的账户、密码、属于这个域的计算机等信息构成的数据库。当计算机联入网络时,域控制器首先要鉴别这台计算是否是属于这个域,用户使用的登录账号是否存在、密码是否正确。
域控制器AD认证
说明
LDAP Browser客户端工具连接Windows AD域控制器。


操作代码
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
public class AuthDemo {
/**
* @param url
* @param name
* @param domain
* @param passwd
* @return
*/
public static boolean auth(String url,String domain,String name,String passwd){
Properties mEnv = new Properties();
mEnv.put(InitialLdapContext.AUTHORITATIVE, "true");
mEnv.put(InitialLdapContext.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
mEnv.put(InitialLdapContext.PROVIDER_URL, url);
mEnv.put(InitialLdapContext.SECURITY_AUTHENTICATION, "simple");
mEnv.put(InitialLdapContext.SECURITY_PRINCIPAL, name+"@"+domain);
mEnv.put(InitialLdapContext.SECURITY_CREDENTIALS, passwd);
try {
new InitialLdapContext(mEnv, null);
return true;
} catch (NamingException e) {
e.printStackTrace();
}
return false;
}
/**
* @param args
*/
public static void main(String[] args) {
String url = "ldap://10.210.81.74:389";
String domain = "what21.com";
String username = "administrator";
String passwd = "12345678";
boolean result = auth(url,domain,username,passwd);
System.out.println(result);
}
}
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
public class AuthDemo2 {
/**
* @param url
* @param userDN
* @param passwd
* @return
*/
public static boolean auth(String url,String userDN,String passwd){
Properties mEnv = new Properties();
mEnv.put(InitialLdapContext.AUTHORITATIVE, "true");
mEnv.put(InitialLdapContext.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
mEnv.put(InitialLdapContext.PROVIDER_URL, url);
mEnv.put(InitialLdapContext.SECURITY_AUTHENTICATION, "simple");
mEnv.put(InitialLdapContext.SECURITY_PRINCIPAL, userDN);
mEnv.put(InitialLdapContext.SECURITY_CREDENTIALS, passwd);
try {
new InitialLdapContext(mEnv, null);
return true;
} catch (NamingException e) {
e.printStackTrace();
}
return false;
}
/**
* @param args
*/
public static void main(String[] args) {
String url = "ldap://10.210.81.74:389";
String userDN = "cn=administrator,cn=users, dc=what21,dc=com";
String passwd = "12345678";
boolean result = auth(url,userDN,passwd);
System.out.println(result);
}
}
创建AD(Active Directory)域控制器用户
说明
创建域控制器账号,设置账号密码和更改账号userAccountControl的属性,让域账号可以正常登录。
代码案例
import java.util.Hashtable;
import javax.naming.ldap.*;
import javax.naming.directory.*;
import javax.naming.*;
import javax.net.ssl.*;
import java.io.*;
public class NewUser{
/**
* @param args
*/
public static void main (String[] args)
{
Hashtable env = new Hashtable();
String adminName = "CN=Administrator,CN=Users,DC=antipodes,DC=com";
String adminPassword = "XXXXXXX";
String userName = "CN=Albert Einstein,OU=Research,DC=antipodes,DC=com";
String groupName = "CN=All Research,OU=Research,DC=antipodes,DC=com";
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
//connect to my domain controller
env.put(Context.PROVIDER_URL, "ldap://mydc.antipodes.com:389");
try {
// Create the initial directory context
LdapContext ctx = new InitialLdapContext(env,null);
// Create attributes to be associated with the new user
Attributes attrs = new BasicAttributes(true);
//These are the mandatory attributes for a user object
//Note that Win2K3 will automagically create a random
//samAccountName if it is not present. (Win2K does not)
attrs.put("objectClass","user");
attrs.put("samAccountName","AlbertE");
attrs.put("cn","Albert Einstein");
//These are some optional (but useful) attributes
attrs.put("giveName","Albert");
attrs.put("sn","Einstein");
attrs.put("displayName","Albert Einstein");
attrs.put("description","Research Scientist");
attrs.put("userPrincipalName","AlbertE@antipodes.com");
attrs.put("mail","relativity@antipodes.com");
attrs.put("telephoneNumber","999 123 4567");
//some useful constants from lmaccess.h
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;
//Note that you need to create the user object before you can
//set the password. Therefore as the user is created with no
//password, user AccountControl must be set to the following
//otherwise the Win2K3 password filter will return error 53
//unwilling to perform.
attrs.put("userAccountControl",Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED+ UF_ACCOUNTDISABLE));
// Create the context
Context result = ctx.createSubcontext(userName, attrs);
System.out.println("Created disabled account for: " + userName);
//now that we've created the user object, we can set the
//password and change the userAccountControl
//and because password can only be set using SSL/TLS
//lets use StartTLS
StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
tls.negotiate();
//set password is a ldap modfy operation
//and we'll update the userAccountControl
//enabling the acount and force the user to update ther password
//the first time they login
ModificationItem[] mods = new ModificationItem[2];
//Replace the "unicdodePwd" attribute with a new value
//Password must be both Unicode and a quoted string
String newQuotedPassword = "\"Password2000\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("userAccountControl",Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWORD_EXPIRED)));
// Perform the update
ctx.modifyAttributes(userName, mods);
System.out.println("Set password & updated userccountControl");
//now add the user to a group.
try{
ModificationItem member[] = new ModificationItem[1];
member[0]= new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", userName));
ctx.modifyAttributes(groupName,member);
System.out.println("Added user to group: " + groupName);
}catch (NamingException e) {
System.err.println("Problem adding user to group: " + e);
}
//Could have put tls.close() prior to the group modification
//but it seems to screw up the connection or context ?
tls.close();
ctx.close();
System.out.println("Successfully created User: " + userName);
}
catch (NamingException e) {
System.err.println("Problem creating object: " + e);
}
catch (IOException e) {
System.err.println("Problem creating object: " + e);
}
}
}
修改AD域控制器用户密码
说明
修改AD用户密码的操作必须通过安全通道,如SSL,TLS或Kerberos,必须信任的CA颁发的证书。
代码案例
import java.util.Hashtable;
import javax.naming.*;
import javax.naming.ldap.*;
import javax.naming.directory.*;
import java.io.*;
public class ModifyPasswd{
/**
* @param args
*/
public static void main (String[] args){
Hashtable env = new Hashtable();
String adminName = "CN=Administrator,CN=Users,DC=antipodes,DC=com";
String adminPassword = "XXXXXXX";
String userName = "CN=Albert Einstein,OU=Research,DC=antipodes,DC=com";
String newPassword = "Password123";
//Access the keystore, this is where the Root CA public key cert was installed
//Could also do this via command line java -Djavax.net.ssl.trustStore....
String keystore = "/usr/java/jdk1.5.0_01/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore",keystore);
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
//specify use of ssl
env.put(Context.SECURITY_PROTOCOL,"ssl");
//connect to my domain controller
String ldapURL = "ldaps://mydc.antipodes.com:636";
env.put(Context.PROVIDER_URL,ldapURL);
try {
// Create the initial directory context
LdapContext ctx = new InitialLdapContext(env,null);
//set password is a ldap modfy operation
ModificationItem[] mods = new ModificationItem[1];
//Replace the "unicdodePwd" attribute with a new value
//Password must be both Unicode and a quoted string
String newQuotedPassword = "\"" + newPassword + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
// Perform the update
ctx.modifyAttributes(userName, mods);
System.out.println("Reset Password for: " + userName);
ctx.close();
}
catch (NamingException e) {
System.out.println("Problem resetting password: " + e);
}
catch (UnsupportedEncodingException e) {
System.out.println("Problem encoding password: " + e);
}
}
}
import java.util.Hashtable;
import javax.naming.*;
import javax.naming.ldap.*;
import javax.naming.directory.*;
import java.io.*;
public class setpasstls{
/**
* @param args
*/
public static void main (String[] args){
Hashtable env = new Hashtable();
String adminName = "CN=Administrator,CN=Users,DC=antipodes,DC=com";
String adminPassword = "XXXXXX";
String userName = "CN=Albert Einstein,OU=Research,DC=antipodes,DC=com";
String newPassword = "Password123";
//Access the keystore, this is where the Root CA public key cert was installed
//Could also do this via command line java -Djavax.net.ssl.trustStore....
String keystore = "/usr/java/jdk1.5.0_01/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore",keystore);
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,adminName);
env.put(Context.SECURITY_CREDENTIALS,adminPassword);
//connect to my domain controller
String ldapURL = "ldap://mydc.antipodes.com:389";
env.put(Context.PROVIDER_URL,ldapURL);
try {
// Create the initial directory context
LdapContext ctx = new InitialLdapContext(env,null);
//Secure the session with TLS
StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
tls.negotiate();
//set password is a ldap modfy operation
ModificationItem[] mods = new ModificationItem[1];
//Replace the "unicdodePwd" attribute with a new value
//Password must be both Unicode and a quoted string
String newQuotedPassword = "\"" + newPassword + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
// Perform the update
ctx.modifyAttributes(userName, mods);
System.out.println("Reset Password for: " + userName);
tls.close();
ctx.close();
}
catch (NamingException e) {
System.out.println("Problem resetting password: " + e);
}
catch (UnsupportedEncodingException e) {
System.out.println("Problem encoding password: " + e);
}
catch (IOException e) {
System.out.println("Problem with TLS: " + e);
}
}
}