实现流程:同步域账户用户名至项目数据库-》若是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); }