實現流程:同步域賬戶用戶名至項目數據庫-》若是IE瀏覽器則通過ActiveXObject獲取PC用戶名-》根據用戶名查詢數據庫-》存在則自動登陸
步驟1:通過定時任務同步AD域賬戶用戶名,代碼如下
package com.honsto.edusys.job; import java.util.Date; import java.util.Hashtable; import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import org.apache.log4j.Logger; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; import com.honsto.core.common.base.ApplicationContextBeanUtil; import com.honsto.edusys.domain.Member; import com.honsto.edusys.service.MemberService; /** * 獲取新增AD域教師用戶保存至數據庫 * * @author liming * */ public class AddTeacherJob extends QuartzJobBean { private final Logger log = Logger.getLogger(this.getClass()); @Override protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException { String jobTitle = this.getClass().getSimpleName(); log.info(jobTitle + " start"); ApplicationContextBeanUtil adb=new ApplicationContextBeanUtil(); try { Date now = new Date(); long start = now.getTime(); int generalNum = 0; MemberService memberService = (MemberService)adb.getBean("memberService"); String host = "192.168.0.1"; // AD服務器IP String port = "389"; // 端口 String username = "example@dbwzx.com"; String password = "examplepassword"; String url = new String("ldap://" + host + ":" + port); Hashtable env = new Hashtable(); DirContext ctx = null; env.put(Context.SECURITY_AUTHENTICATION, "simple");// 一種模式,不用管,就這么寫就可以了 env.put(Context.SECURITY_PRINCIPAL, username); env.put(Context.SECURITY_CREDENTIALS, password); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, url); try { ctx = new InitialDirContext(env); SearchControls searchCtls = new SearchControls(); searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); String searchFilter = "(&(objectCategory=person)(objectClass=user)(name=*))"; String searchBase = "DC=dbwzx,DC=com"; String returnedAtts[] = {"userPrincipalName"}; searchCtls.setReturningAttributes(returnedAtts); NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls); // 初始化搜索結果數為0 int totalResults = 0; while (answer.hasMoreElements()) { SearchResult sr = (SearchResult) answer.next(); // 判斷是否是OU=學校下的數據 if (sr.getName().indexOf("OU=學校") > 0) { Member member = null; String memberUserName = null; Attributes Attrs = sr.getAttributes();// 得到符合條件的屬性集 if (Attrs != null) { try { for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore();) { Attribute Attr = (Attribute) ne.next();// 得到下一個屬性 // 如果屬性名是userPrincipalName if("userPrincipalName".equals(Attr.getID().toString())){ System.out.println("*********************************************************************"); System.out.println(" 屬性名:"+ Attr.getID().toString()); // 讀取屬性值 for (NamingEnumeration e = Attr.getAll(); e.hasMore(); totalResults++) { memberUserName = e.next().toString(); System.out.println(" 屬性值:"+ memberUserName); } System.out.println("*********************************************************************"); } break; } } catch (javax.naming.NamingException e) { System.err.println("Throw Exception : " + e); } } member = memberService.findMemberByLoginName(memberUserName); if(member != null){ continue; // 跳過 } else { generalNum ++; // 初始化保存 member = new Member(); member.setUsername(memberUserName); memberService.saveMember(member); } } } } catch (AuthenticationException e) { System.out.println("身份驗證失敗!"); e.printStackTrace(); } catch (javax.naming.CommunicationException e) { System.out.println("AD域連接失敗!"); e.printStackTrace(); } catch (Exception e) { System.out.println("身份驗證未知異常!"); e.printStackTrace(); } finally { if (null != ctx) { try { ctx.close(); ctx = null; } catch (Exception e) { e.printStackTrace(); } } } long end = System.currentTimeMillis(); log.info(jobTitle + " end,used:" + ((end - start) /1000) + "seconds, add size:->" + generalNum); } catch (Exception e) { log.error(jobTitle + " Exception:", e); } } }
步驟2:在IE瀏覽器下獲取PC用戶名並且提交登陸表單,代碼如下:
<script type="text/javascript"> $(function(){ // 登陸失敗和退出系統操作都會返回error信息,通過判斷error是否為空控制系統在用戶退出及需要輸入賬號密碼時不使用AD域登陸 <c:if test="${empty error}"> // 判斷瀏覽器是不是ie var isIE = false; var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字符串 var isOpera = userAgent.indexOf("Opera") > -1; if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera) { isIE = true; }; // 因為ie10-ie11的版本問題,不再支持document.all判斷,所以ie判斷函數要重新寫了 if(!isIE){ isIE = !!window.ActiveXObject || "ActiveXObject" in window; } // 如果是ie,則獲取以下信息並登陸 if(isIE){ try { var WshNetwork = new ActiveXObject("WScript.Network"); jQuery("#browserName").val("IE"); jQuery("#userOfAD").val(WshNetwork.UserName); alert(WshNetwork.UserName); jQuery("#form1").submit(); } catch(e) { var promptStr = "自動登錄需要允許ActiveXObject腳本運行,請您先進行設置!" + "\n設置步驟:在“IE-Internet選項-安全-自定義級別-ActiveX控件和插件-對未標記為可安全執行腳本的ActivesX控件”,設置為“提示”或“啟用”"; alert(promptStr); } } </c:if> }) </script>
步驟3:修改Controller,用戶使用IE瀏覽器時根據用戶名查詢數據庫,根據查詢結果進行相應操作,代碼如下:
// IE瀏覽器 if ("IE".equals(browserName)) { // AD域登錄 String userOfAD = request.getParameter("userOfAD"); if(StringUtils.isBlank(userOfAD)){ // 登陸錯誤返回登陸頁 return new ModelAndView("login", map); } // 判斷改AD用戶是否存在 System.out.println("當前用戶名" + userOfAD); Member member = memberService.findMemberByLoginName(userOfAD); if (member != null) { member.setLastLoginDate(new Date()); memberService.updateMember(member); request.getSession().setAttribute(Constant.USER, member); if (StringUtils.isNotBlank(returnURL)) { response.sendRedirect(returnURL); return null; } return new ModelAndView( new RedirectView( "/list.do"), map); } map.put("error", "noadusername"); // 登陸錯誤返回登陸頁 return new ModelAndView("login", map); }