1. 程式人生 > >LDAP賬號同步和Windows域整合驗證

LDAP賬號同步和Windows域整合驗證

應用場景

  • 應用系統中的賬號資訊除了本地建立的之外,還要有LDAP中的,並且隨時與LDAP中的最新資料一致;
  • 公司所有人的電腦都在一個域中管理,員工通過域賬號和密碼登入他的計算機之後,在登入應用系統之後不再需要輸入密碼,直接進入系統;
  • 如果員工擁有多個不同的域賬號和密碼,那麼他也可以在選擇任意一個域賬號來登入應用系統(而不僅僅是登入計算機那個域賬號和密碼);

目標功能

  • 1,LDAP賬號同步
    把LDAP中的使用者資料同步到本地資料中
  • 2,LDAP使用者登入驗證
    根據使用者提供的使用者名稱和密碼驗證使用者是否為合法的域使用者
  • 3,Windows域整合驗證
    比如一個資訊管理系統,當用戶使用域中(域控,ActiveDirectory)的計算機登入資訊管理系統的時候,由於該使用者在登入計算機的時候已經通過了身份驗證,所以不需要再次輸入使用者名稱和密碼而直接進入資訊管理系統。

測試環境準備

伺服器IP:192.168.116.128

伺服器域資訊:

Active Directory 狀態:

功能:LDAP賬號同步

首先,需要獲取到LdapContext:

	private LdapContext getLdapContext()throws NamingException{
		Hashtable<String,String> hashtable = new Hashtable<String,String>();
		hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		hashtable.put(Context.PROVIDER_URL, "ldap://192.168.116.128:389");//伺服器地址
		hashtable.put(Context.SECURITY_AUTHENTICATION, "simple");
		hashtable.put(Context.SECURITY_PRINCIPAL, "
[email protected]
");//使用者名稱 hashtable.put(Context.SECURITY_CREDENTIALS, "321%cba");//密碼 return new InitialLdapContext(hashtable,null); }


然後進行相關的搜尋設定:

		LdapContext  ctx = getLdapContext();
                //設定分頁大小
		ctx.setRequestControls(new Control[] { new PagedResultsControl(15, Control.NONCRITICAL) });
		
		SearchControls control = new SearchControls();
		
		//搜尋方式
		control.setSearchScope(SearchControls.SUBTREE_SCOPE);//Search the entire subtree rooted at the named object. 
		//control.setSearchScope(SearchControls.ONELEVEL_SCOPE);//Search one level of the named context
		//control.setSearchScope(SearchControls.OBJECT_SCOPE);//Search the named object
		
		//搜尋欄位
		String returnedAtts[] = { "displayName", "mail", "telephoneNumber","thumbnailPhoto" };//姓名,郵箱,電話,頭像
		control.setReturningAttributes(returnedAtts);
		
		//設定ou和filter
		String ou = "ou=users,ou=beijing,dc=abc,dc=com";
		String filter = "(&(objectClass=user)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))";

最後,發起搜尋請求,解析搜尋結果:

NamingEnumeration<SearchResult> results = ctx.search(ou, filter, control);
		while (results != null && results.hasMoreElements()) {
			SearchResult entry = (SearchResult) results.next();
			String empName = getValueFromAttribute(entry.getAttributes().get(returnedAtts[0]));
			String mail = getValueFromAttribute(entry.getAttributes().get(returnedAtts[1]));
			String telephone = getValueFromAttribute(entry.getAttributes().get(returnedAtts[2]));
			byte[] photoBytes = null;
			Attribute att = (Attribute) entry.getAttributes().get("thumbnailPhoto");
			if(att!=null){
				photoBytes = (byte[])(att.get(0));
			}
			System.out.println(empName+"|"+mail+"|"+telephone+"|"+(photoBytes==null ? 0 : photoBytes.length));
		}

功能:LDAP使用者登入驗證

我的實現方式如下,有更好方法的朋友還請指教:

private boolean validate(String username,String pwd)throws NamingException{
		Hashtable<String,String> hashtable = new Hashtable<String,String>();
		hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
		hashtable.put(Context.PROVIDER_URL, "ldap://192.168.116.128:389");//伺服器地址
		hashtable.put(Context.SECURITY_AUTHENTICATION, "simple");
		hashtable.put(Context.SECURITY_PRINCIPAL, username);//使用者名稱
		hashtable.put(Context.SECURITY_CREDENTIALS, pwd);//密碼
		return new InitialLdapContext(hashtable,null)!=null;
	}

功能:Windows整合驗證登入

下載工具後解壓,然後:

複製jar包frdoumesspitc7.jar到tomcat的/lib目錄下 

複製SSPAuthentification.dll和SSPAuthentificationx64.dll到tomcat的/bin目錄下

在應用的web.xml中增加如下配置:

<security-constraint>
      <display-name>Example Security Constraint</display-name>
      <web-resource-collection>
         <web-resource-name>Protected Area</web-resource-name>
	 	 <!-- Define the context-relative URL(s) to be protected -->
         <url-pattern>/auth.do</url-pattern>
	 	 <!-- If you list http methods, only those methods are protected -->
	 	 <http-method>DELETE</http-method>
         <http-method>GET</http-method>
         <http-method>POST</http-method>
	 	 <http-method>PUT</http-method>
      </web-resource-collection>
      <auth-constraint>
         <!-- Anyone with one of the listed roles may access this area 
	 	 <role-name>utilisateurs</role-name>
	 	 <role-name>users</role-name>
	 	 <role-name>everyone</role-name>-->
	 	 <role-name>everyone</role-name>
      </auth-constraint>
    </security-constraint>

    <!-- Default login configuration -->
    <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>Example Spnego</realm-name>
    </login-config>

就這樣,tomcatspnego就能使用了。這裡使用到了Tomcat的目錄保護功能,而tomcatspnego應該是對tomcat的驗證功能做了修改,增加了域資訊的檢查。這裡連沒有配置域伺服器ip地址都沒有配置,tomcatspnego具體如何實現域資訊監測就不太清楚了。

接下來,在我們自己的應用身份驗證中需要用到tomcatspnego留給我們的標記:

    @RequestMapping(value = "/auth")
    public String ntlmAuth(HttpServletRequest request,HttpServletResponse response,HttpSession session){
    	Principal princ = request.getUserPrincipal();
    	if (isLogined()) {
                return "redirect:index.do";
        }
    	if(princ!=null){
    		session.setAttribute("princpalNameInSession", princ.getName());
    	}
    	return "redirect:index.do";
    }

    @RequestMapping("/login")
    public ModelAndView login(String loginName,String password,HttpServletResponse response,HttpSession session,HttpServletRequest request) {
    	if(!response.isCommitted()){
    		ModelAndView mav = new ModelAndView();
			mav.setViewName("login");
    		User user = null;
    		Config config = Config.getInstance(true);
    		if(notEmpty(loginName) && notEmpty(password)){//如果使用者名稱和密碼都存在,普通登入,或域賬號登入
    			user = userService.getEntityByProperty(User.class, "userName", loginName);
    			if(user==null || user.getStatus()!=UserStatus.Active ){
    				mav.addObject("noUserError", "使用者名稱不存在!");
    			}else{
    				if(user.getType()==UserType.Domain && config.isUseLdapValidate()){//域使用者
    					if(domainLoginValidate(loginName,password,request,config)){
    						mav.setViewName("redirect:index.do");//域登入成功
    					}
    				}else{
    					if(localLoginValidate(user,password)){
    						mav.setViewName("redirect:index.do");//本地登入成功
    					}else{
    						mav.addObject("passwordError", "密碼輸入錯誤!");
    					}
    				}
    			}
    		}else if(domainLoginValidateByNtlm(request)){//存在域Ntlm變數,嘗試域登入
    			//則根據域變數獲取到使用者名稱
    			String princpalName = getPrincpalUserName(request);
    			user = userService.getEntityByProperty(User.class, "userName", princpalName);
    			
    			if(user!=null){
    				log.info("使用者:"+loginName+",通過獲取到本機域資訊直接登入成功!");
    			}else{
    				mav.addObject("error","已經檢測到您為域使用者,但是在系統中沒有查詢到您的使用者資訊");
    			}
    		}else{
    			//使用者名稱和密碼以及域變數都不存在,重定向到登入頁面
    			mav.setViewName("redirect:loginUI.do");
    		}
    		//然後獲取到user資訊,並載入許可權資訊,設定“已登入”標誌
    		if(user!=null){
    			prepareFunctionPoint(session,user);
    		}
    		return mav;
    	}
    	return null;
    }

    @RequestMapping("/index")
    public String index(HttpServletRequest request,HttpServletResponse response,HttpSession session){
    	if(!response.isCommitted()){
			if (isLogined()) {
				return "main";
			} 
			Config config = Config.getInstance(true);
			if(!config.isUseLdapValidate()){
				return "redirect:loginUI.do";
			}
			// 則嘗試根據域變數獲取到使用者資訊;
			User user = getUserFromDbByDomainUserName(request);
			if (user != null) {
				prepareFunctionPoint(session, user);
				return "main";
			}
			return "redirect:loginUI.do";
    	}
    	return null;
	}

說明:

這裡把應用的首頁設定為/auth.do,以便於當用戶直接訪問/的時候直接跳轉到/auth.do;

在進入ntlmAuth方法之前,系統已經利用tomcatspnego來嘗試域驗證;

在auth方法中嘗試獲取tomcatspnego給我們留下來的變數,並儲存起來;

從定向到index.do,index中嘗試通過域變數來獲取使用者資訊(獲取成功表示域登陸成功);

login方法正常接收使用者名稱和密碼,可以進行本地賬號驗證和域賬號驗證。

# 2018-08-15更新

發現還有朋友在關注這個問題,我順便更新一下。

我寫的的這個適用於Tomcat7,發現Tomcat8用不了。那Tomcat8怎麼做呢?其實官方文件裡有說明:

點到這裡面,找到第三方工具,我用過這個工具還不錯,你還可以順便研究研究其他的。

不好意思我買了個關子,其實直接給出下面這個地址就好了。我多記錄了一下我怎麼找到這個資源的。

相關推薦

LDAP賬號同步Windows整合驗證

應用場景 應用系統中的賬號資訊除了本地建立的之外,還要有LDAP中的,並且隨時與LDAP中的最新資料一致; 公司所有人的電腦都在一個域中管理,員工通過域賬號和密碼登入他的計算機之後,在登入應用系統之後不再需要輸入密碼,直接進入系統; 如果員工擁有多個不同的域賬號和密碼,

簡單粗暴的iptables命令說明windows下telnet驗證

    先說一個場景,我因為在開發環境中需要連線linux伺服器的memcache服務,但伺服器肯定是開了ip

Java驗證Ldap賬號讀取Ldap中所有使用者

一、驗證Ldap使用者public class LDAPAuthentication{ private final String URL = "ldap://192.168.1.205:389/"; private final String BASED

微軟同步發行Windows 10Windows 10 Mobile系統更新

系統更新 桌面 視覺 音樂播放 enter 右鍵 功能 顏色 邊框 微軟今天同步公布了新的 Windows 10 Redstone PC 和 Windows 10 Mobile 預覽版。PC 版本是 Build 14271。Mobile 版本是 Build 14267.

白話windows server 2012 r2windows 7創建ad與配置(安全版)

關閉 logo 打不開 cmd 2012 r2 以太網 子網 int 180天 文章的可讀性非常重要,這裏提供的是一鍵式操作指南,即使之前完全沒有接觸,也可以配置完成。 ad域的創建是為了便於公司的集中化管理,提高公司運作效率和安全性。 我的操作環境,本機是kali lin

Windows Server 2012 R2/2016 此工作站間的信任關系失敗

脫域 此工作站和主域間的信任關系失敗 今天給客戶Exchange 服務器出現了脫域的情況,當使用域帳戶登錄時出現了“此工作站和主域間的信任關系失敗”的情況。造成這種的可能原因: 域內存在了多臺SID一樣的計算機; 計算機對象在AD中意外刪除; 客戶端的帳戶密碼更新失敗; 時間超過5分鐘; AD復制問

如果讓MAC OX MACOS High Sierra 加入windows 管理

MAC 蘋果 加入 域 windows最近遇到一個問題: 要讓最新的MAC系統加入windows 的 域中。想了很多辦法 最後終於克服。 由於最新版的 MAC OSX MACOS High Sierra 系統不能像前面的版本一樣通過賬戶中設定加入,所以需要通過命令來操作: 第一步 修改計算機的網卡設定 把DN

Ajax同步非同步的區別,如何解決跨問題

同步的概念應該是來自於OS中關於同步的概念:不同程序為協同完成某項工作而在先後次序上調整(通過阻塞,喚醒等方式).同步強調的是順序性.誰先誰後.非同步則不存在這種順序性. 同步:瀏覽器訪問伺服器請求,使用者看得到頁面重新整理,重新發請求,等請求完,頁面重新整理,新內容出現,使用者看到新內容,進行下一步操作。

Harbor使用者機制、映象同步與Kubernetes的整合實踐_Kubernetes中文社群

目錄: 一、Harbor的安全機制 二、Harbor的映象同步 三、Harbor與K8s的整合實踐 四、兩個小貼士 五、總結 Habor是由VMWare公司開源的容器映象倉庫。事實上,Habor是在Docker Registry上進行了相應的企業級擴充套件,從而獲得了更加廣泛的應用,這些新的企

ASP.NET中的FormsWindows混合驗證

摘要:ASP.NET開發人員曾經問到過如何使用Forms和Windows混合驗證。Paul Wilson提供了一個解決方案來獲得Windows使用者名稱,或者,將使用者轉向登入頁面。 簡介 我曾經遇到很多ASP.NET開發人員問到如何使用Forms和Windows混合

windows 2012環境出現(此工作站之間的信任關係失敗)

當您登入到域環境中執行 Windows 7 的計算機上時,您會收到以下錯誤訊息:此工作站和主域之間的信任關係失敗。 解決方案 若要解決此問題,請從域中刪除計算機,然後將計算機連線到域。若要執行此操作,請執行以下步驟: 使用本地管理員帳戶登入到計算機上。 單擊開始,右

mysql5.7配置主從同步windowslinux從

1、下載mysql2、master配置windows修改E:\ProgramData\MySQL\MySQL Server 5.7目錄的my.ini檔案:# master服務唯一標識 server-id = 1 # 二進位制同步資料檔案 log-bin = mysql-bin

【軟體使用】解決Firefox在ubuntuWindows之間同步問題

【水話】 大家要急著解決,直接跳到下面 話說,以前一直都是用Chrome的,但自從Google在香港的伺服器搬會美國以後,整個人都不好了,之前靠VPN解決,但還是有點麻煩,而且又是VPN伺服器有崩掉。無奈之下轉向火狐。 不要問我為什麼選者Firefox,因為任性。哈哈哈,其

SqlServer2008登入由windows身份認證改sqlserverwindows身份驗證模式的方法

1、右擊資料庫連線,如圖: 2、點選屬性 在安全性中將sqlserver和windows身份驗證模式選中 3、在安全性中,登入名中找到sa,右擊屬性,常規中設定sa的密碼,如下 4、接著,在狀態中登入那塊將登入由禁用改為啟用 這樣設定,然後用sqlserver

windows server 2016 伺服器建立AD DNS 主

1.準備兩臺伺服器作為主域伺服器AD1,輔域伺服器AD22.保證AD1,AD2網路正常3.安裝AD域服務和DNS服務4.首先配置主域伺服器AD1,開啟DNS在正向查詢區域處右鍵,新建區域選擇主要區域輸入域名下一步預設不動態更新即可點選完成可以看到正向區域列表中增加了剛才新增的

安裝黑蘋果MacWindows雙系統之後的時間同步

很多同學在安裝黑蘋果Mac和Windows雙系統之後都會遇到一個問題                                                                  

rsync實現windowswindows之間的數據同步

同步 ror test uid ima 結構 nor 數據 pan 一:環境   1、同步對象:測試數據   2、服務端:Windows Server 2008 R2   3、客戶端:Windows7 旗艦版64位   4、服務端rsync版本:cwRsync

用python的matplotlibnumpy庫繪製股票K線均線成交量的整合效果(含量化驗證交易策略程式碼)

     在用python的matplotlib和numpy庫繪製股票K線均線的整合效果(含從網路介面爬取資料和驗證交易策略程式碼)一文裡,我講述了通過爬蟲介面得到股票資料並繪製出K線均線圖形的方式,在本文裡,將在此基礎上再引入成交量效果圖,並結合量價理論,給出並驗證一些交易策略

ajax主之間的跨問題

復制 jquery對象 body content iframe .com post {} log 【轉發】http://www.cnblogs.com/adtxgc/p/4691872.html iframe解決ajax主域和子域之間的跨域問題 在某些應用場景下,需

線程同步互斥的區別

之間 方法 無法 spa lock zed 模式 col 一定的 互斥是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。 同步是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。