项目学习主题四:Activedirectory

配置信息config.xml
<pre name="code" class="java">Conf>
	<ADinformation>

		<ADldapHost>ldap://11.241.14.333:389</ADldapHost>
		<ADDN>CN=AAA,OU=BBB,OU=CCC,DC=DDD,DC=EEE</ADDN>
		<ADpassword>ZXC</ADpassword>
		<ADsearchBaseDN>ou=CCC,dc=DDD,dc=com</ADsearchBaseDN>
	</ADinformation>
</Conf>
 
一初始化:
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import play.mvc.Controller;
/**
 * This class is used to return informations for an AD connection.
 * 初始化				
 *				
 **/
public class ADconnect {
	

  	public static Properties getProps()throws Exception{
  		try{
	  		Map<String, String> map = Readxml.getXmlInfo("config.xml");
	  		String ldapHost=map.get("ADldapHost");
			String DN=map.get("ADDN");
			String password=map.get("ADpassword");
			String searchBaseDN=map.get("ADsearchBaseDN");
	
			Properties props=new Properties();
			props.put(Context.INITIAL_CONTEXT_FACTORY, 
				"com.sun.jndi.ldap.LdapCtxFactory");		
			props.put(Context.PROVIDER_URL, ldapHost);
			props.put("java.naming.ldap.version", "3");								
			props.put(Context.SECURITY_PRINCIPAL, DN);								
			props.put(Context.SECURITY_CREDENTIALS, password);					
			props.put("ADsearchBaseDN", searchBaseDN);
			props.put(Context.REFERRAL,"follow");
			return props;
		}catch(Exception ex)
		{
			throw ex;
		}
  	}
}
</pre><pre code_snippet_id="363364" snippet_file_name="blog_20140526_22_5959525" name="code" class="java">
二:在AD环境中认证账户信息
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.xml.sax.SAXException;
/**
 * This class is used to authenticate or check informations for an account.
 **/

public class ADauthenticate extends Controller {
	
	public static Boolean checkByPassword(String password)
			throws NamingException, SAXException, IOException {
		
		Map<String, String> map = Readxml.getXmlInfo("config.xml");
		String DistinguishedName = "";
		Object obj = Cache.get("DistinguishedName");
		if (obj != null) {
			DistinguishedName = obj.toString();
		} else {
			DistinguishedName = session("DistinguishedName");
		}
		String DN = DistinguishedName;
		String url = map.get("ADldapHost");

		// get DirContext for AD connect
		Properties props = new Properties();
		DirContext ctx;
		props.put(Context.SECURITY_AUTHENTICATION, "simple");
		props.put(Context.SECURITY_PRINCIPAL, DN);
		props.put(Context.SECURITY_CREDENTIALS, password);
		props.put(Context.INITIAL_CONTEXT_FACTORY,
				"com.sun.jndi.ldap.LdapCtxFactory");
		props.put(Context.PROVIDER_URL, url);
		try {
			ctx = new InitialDirContext(props);
			ctx.close();
			//if return true, this account has successfully login.
			return true;
		} catch (NamingException err) {
			//else, it failed to login.
			return false;
		}
	}
	/**
	 * This function is used to check informations of an account.
	 */
</pre><pre code_snippet_id="363364" snippet_file_name="blog_20140526_10_8218727" name="code" class="java">//将用户的各个属性以变量形式声明在类Authbean里
	public static Boolean checkInfo(Authbean Info)
			throws Exception {
		try {
			ADsearch ad = new ADsearch();
			String answer = ad.searchResult(session("AccountID"),
					(ADsearch.searchForWhat.S_ANSWER));
			if (!Info.answer.equals(answer)) {
				//got wrong informations.
				return false;
			}
		}catch(Exception ex)
		{
			throw ex;
		}
		//information matches that in AD.
		return true;
	}
}
</pre>三:AD修改关键代码<pre>
<pre name="code" class="java">
public class ADmodify {
	
	public enum modifyWhat{
		M_LOCK,
		M_UNLOCK,
		M_UNLOCK2,
  		M_QUESTION,	//问题
  		M_ANSWER,	//回答
  		
	}
	
	/**
	 * This function is used to do simple AD modifies
	 */
	public static void modifyAccount(modifyWhat What,String content) throws Exception{
		Properties props = null;
		try {
			ADsearch ad=new ADsearch();
			int i;
			props = ADconnect.getProps();
			ModificationItem[] mods = new ModificationItem[1];
			Attribute attr2Change = null;
			boolean flg=false;
			switch(What){
			case M_LOCK:
				i=Integer.parseInt(ad.searchResult(String.valueOf(Cache.get("AccountID")), ADsearch.searchForWhat.S_USERACCOUNTCONTROL));
				attr2Change = new BasicAttribute("userAccountControl", String.valueOf(i|2));
				break;
			case M_UNLOCK:
				i=Integer.parseInt(ad.searchResult(String.valueOf(Cache.get("AccountID")), ADsearch.searchForWhat.S_USERACCOUNTCONTROL));
				if(i%4!=0){
					attr2Change = new BasicAttribute("userAccountControl", String.valueOf(i-2));
				}
				else{
					attr2Change = new BasicAttribute("userAccountControl", String.valueOf(i));
				}
				flg=true;
				break;
			case M_UNLOCK2:
				attr2Change=new BasicAttribute("lockoutTime","0");
				break;
			case M_QUESTION:
				attr2Change = new BasicAttribute("extensionAttribute1", content);
				break;
			case M_ANSWER:
				attr2Change = new BasicAttribute("extensionAttribute2", content);
				break;
			default:
				break;
			}												
			DirContext ctx = new InitialDirContext(props);
			mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, attr2Change);
			String DistinguishedName = "";
			Object obj = Cache.get("DistinguishedName");
			if (obj != null){
				DistinguishedName = obj.toString();
			}else{
				DistinguishedName = session("DistinguishedName");
			}
			ctx.modifyAttributes(DistinguishedName, mods);
			if(flg){
				modifyAccount(modifyWhat.M_UNLOCK2,"");
				flg=false;
			}
		}catch(Exception ex){
			throw ex;	
		}
	}
};
</pre><pre code_snippet_id="363364" snippet_file_name="blog_20140526_14_6222669" name="code" class="java">四:AD 查找
<pre name="code" class="java">import java.util.Enumeration;
import java.util.Properties;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
/**
 * This class is used to search account informations			
 **/
public class ADsearch {	
  	public String searchType="person";
  	public String searchAttr="sAMAccountName";
  	public enum searchForWhat{
  		S_EXIST,
  		S_LOCKED,
  		S_INITIAL,
  		S_DISTINGUISHEDNAME,
  		S_QUESTION,
  		S_ANSWER,
  		S_USERACCOUNTCONTROL,
  	
  	};
  	
  	/**
  	 * return a search result value according to the needs.
	 * @param searchTxt 
	 * 		search text
	 * @param What 
	 * 		attribute to search for
	 * @return String 
	 * 		search result values
  	 * @throws Exception 
	 */

  	public String searchResult(String searchTxt,searchForWhat What)
  	throws Exception{
  	
  		Properties props= ADconnect.getProps();  		
  		String result="";
  		try{
  			DirContext ctx = new InitialDirContext(props);
  			String searchFilter;									
  			searchFilter = "(&(objectClass="+searchType+")("+searchAttr+"="+ searchTxt+"))";
  			SearchControls searchControls = new SearchControls();								
  			searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
  			NamingEnumeration<?> searchResultEnum = ctx.search(props.getProperty("ADsearchBaseDN"),searchFilter,searchControls);
  			//switch Search Functions
  			switch (What){
  				case S_EXIST:
  					result=existSearch(searchResultEnum,ctx);
  					break;
  				case S_LOCKED:
  					result=lockedSearch(searchResultEnum,ctx);
  					break;
  				case S_INITIAL:
  					result=initialSearch(searchResultEnum,ctx);
  					break;
  				case S_DISTINGUISHEDNAME:
  					result=otherSearch("distinguishedName",searchResultEnum,ctx);
  					break;
  				case S_QUESTION:
  					result=otherSearch("extensionAttribute1",searchResultEnum,ctx);
  					break;
  				case S_ANSWER:
  					result=otherSearch("extensionAttribute2",searchResultEnum,ctx);
  					break;
  				case S_USERACCOUNTCONTROL:
  					result=otherSearch("userAccountControl",searchResultEnum,ctx);
  					break;
  				default:
  					break;
  			}
  			//end of the switched function
  		}catch(Exception ex){
  			throw ex;
  		}
  		return result;
  	}
  
  	/**
  	 * Decide whether this id exists
	 */
  	private String existSearch(NamingEnumeration<?> searchResultEnum,DirContext ctx)
  		throws NamingException {
  		try {
	  		if(searchResultEnum.hasMore()){
	  			//id exists.
	  			return "true";  
	  		}
	  		//id non-exists.
	  		return "false";  
  		} catch(NamingException ex){
  			throw ex;
  		}
  	}
  	
  	/**
  	 * Decide whether this id is locked.
	 * @return String
	 * 				"true" represents "locked" while "false" represents "unlocked"
	 * @throws NamingException
	 */
  	private String lockedSearch(NamingEnumeration<?> searchResultEnum,DirContext ctx)
  		throws NamingException {
  		try {
	  		if(searchResultEnum.hasMore()){
	  			SearchResult searchResult = (SearchResult) searchResultEnum.next();				
	  			NamingEnumeration<?> names = searchResult.getAttributes().getAll();
	  			while(names.hasMore()){
	  				Attribute attr=(Attribute)names.nextElement();
	  				//decide whether this id is active or not
	  				if(attr.getID().equals("lockoutTime")){
	  					Enumeration<?> attrValEnum=attr.getAll();
	  					if (attrValEnum.hasMoreElements()) {							
	  						String elem = (String) attrValEnum.nextElement();
	  						if(elem!=null && !elem.equals("0")){
	  							//if return true, this account is locked.
	  							return "true";
	  						}
	  					}
	  				}
	  			}		
	  		}		
	  		//else, this account is not locked.
	  		return "false";
  		} catch(NamingException ex){
  			throw ex;
  		}
  	}
  	
  	/**
  	 * Decide whether this id is the first time to login.
	 */
  	private String initialSearch(NamingEnumeration<?> searchResultEnum,DirContext ctx)
  		throws NamingException{
  		try {
	  		if(searchResultEnum.hasMore()){
	  			SearchResult searchResult = (SearchResult) searchResultEnum.next();				
	  			NamingEnumeration<?> names = searchResult.getAttributes().getAll();
	  			while(names.hasMore()){
	  				Attribute attr=(Attribute)names.nextElement();
	  				if(attr.getID().equals("otherMobile"))
	  					return "false";
	  			}	
	  		}
	  		return "true";  //id first login
	  	} catch(NamingException ex){
				throw ex;
		}
  	}
  	
  	/**
  	 * Return an attribute value of a user.
	 */
  	private String otherSearch(String search,NamingEnumeration<?> searchResultEnum,DirContext ctx)
  	throws NamingException{
  		try {
	  		String result="";
	  		if(searchResultEnum.hasMore()){
	  			SearchResult searchResult = (SearchResult) searchResultEnum.next();				
	  			NamingEnumeration<?> names = searchResult.getAttributes().getAll();
	  			while(names.hasMore()){
	  				Attribute attr=(Attribute)names.nextElement();
	  				if(attr.getID().equals(search)){
	  					Enumeration<?> attrValEnum=attr.getAll();
	  					if (attrValEnum.hasMoreElements()) {							
	  						result = (String)attrValEnum.nextElement();						
	  					}
	  				}
				}	
			}
			return result;
  		} catch(NamingException ex){
			throw ex;
  		}
	}
}
</pre><pre code_snippet_id="363364" snippet_file_name="blog_20140526_17_9036160" name="code" class="java">五:AD账户密码重置
<pre name="code" class="java">//This class is used to reset password for an account.				
public class ADresetpwd {
	public LdapContext ctx = null;
/**
 * This function is used to reset password for an account.
 */
	public boolean resetPassword(String distinguishedName,String newPassword){
		try{
			initial_Ldap();
			mod_Pwd(distinguishedName,newPassword);
			close_Ldap();
		}catch(Exception e){
			e.printStackTrace();
			//if return false, this action has failed.
			return false;
		}
		//if return true, password has been reset successfully.
		return true;
	}
	/**
	 * This function is used to connect AD using the security mode.
	 * 
	 * @throws Exception
	 */
	private void initial_Ldap() throws Exception {
		System.setProperty("javax.net.ssl.trustStore", Utils.keystore);
		System.setProperty("javax.net.ssl.trustStorePassword", Utils.keyPassword);
		Hashtable<String, String> env = new Hashtable<String, String>();
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		env.put(Context.SECURITY_PRINCIPAL, Utils.adminName);
		env.put(Context.SECURITY_CREDENTIALS, Utils.adminpassword);
		env.put(Context.SECURITY_PROTOCOL, "ssl");
		env.put(Context.PROVIDER_URL, Utils.ldapURL);
		
		try {
			ctx = new InitialLdapContext(env, null);
		} catch (NamingException e) {
			e.printStackTrace();
			throw e;
		} 
	}
</pre><pre code_snippet_id="363364" snippet_file_name="blog_20140526_20_3037349" name="code" class="java"><span style="white-space:pre">	</span>//class Utils
<span style="white-space:pre">	</span>//public static final String adminName = "ssss@silver.com";
<span style="white-space:pre">	</span>//public static final String adminpassword = "mmmmm";
<span style="white-space:pre">	</span>//public static final String keystore = "c:/silverca.keystore"; 
<span style="white-space:pre">	</span>//public static final String keyPassword = "silver";
<span style="white-space:pre">	</span>//public static final String ldapURL ="ldaps://11.55.222.333:444";
	
	/**
	 * This function is used to modify password for an account.
	 */
	private void mod_Pwd(String username, String password) throws UnsupportedEncodingException, NamingException {
		ModificationItem[] mods = new ModificationItem[1];
		String newQuotedPassword = "\"" + password + "\"";
		try {
			byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
			mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
					new BasicAttribute("unicodePwd", newUnicodePassword));
			ctx.modifyAttributes(username, mods);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
			throw e1;
		} catch (NamingException e2) {
			e2.printStackTrace();
			throw e2;
		}
	}
	/**
	 * This function is to close an AD connection.
	 * 
	 * @throws NamingException
	 */
	private void close_Ldap() throws NamingException{
		try {
			ctx.close();
		} catch (NamingException e) {
			e.printStackTrace();
			throw e;
		}
	}
}


 
 
</pre><pre code_snippet_id="363364" snippet_file_name="blog_20140526_22_5959525" name="code" class="java">

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值