`

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, "Administrator@abc.com");//用户名
		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集成验证登录

这个功能,使用到了工具http://tomcatspnego.codeplex.com/
下载工具后解压,然后:
复制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方法正常接收用户名和密码,可以进行本地账号验证和域账号验证。






分享到:
评论

相关推荐

    Springboot-LDAP针对AD域控做用户和组织进行同步.zip

    本文将深入探讨如何使用Spring Boot 2.x与LDAP集成,特别是在与Active Directory(AD)域控制器交互,实现用户和组织的同步。 首先,让我们了解Spring Boot 2.x。Spring Boot是Spring框架的一个扩展,它简化了创建...

    H3C CAS LDAP帐号同步特性说明.pdf

    H3C CAS(Cloud Agile Service)是一个云计算管理平台,它支持与LDAP进行集成以实现用户账号同步。配置步骤包括: 1. **特性应用场合**:适用于需要统一管理用户身份和权限的多应用环境,如数据中心、虚拟化环境等...

    JAVA使用Ldap操作AD域的方法示例

    在本文中,我们将深入探讨...理解这些概念和API的使用是实现AD域集成的关键。通过以上介绍和示例代码,你应该能够开始编写自己的AD域操作功能。记得在实际工作中根据具体需求和环境进行调整,以确保安全性和可靠性。

    Linux系统下LDAP的实现

    5. 客户端配置:在Linux系统中,可以使用pam_ldap或nss_ldap模块来与LDAP服务器集成,从而实现通过LDAP进行用户认证和账号信息查询。 6. 测试配置:通过LDAP客户端工具,如ldapsearch、ldapadd、ldapmodify等进行...

    基于LDAP统一用户管理系统的研究与应用

    4. 集成和同步:将新的用户信息或权限变更实时同步到所有应用系统,确保数据的一致性。 5. 性能优化:通过缓存、索引和负载均衡等手段,提升大规模用户认证的性能。 本文档可能包含的“Paper\pdf\left.htm”等图像...

    理解与应用LDAP服务器

    在实际应用中,LDAP不仅可以用于存储用户账号信息,还可以与其他系统集成,如邮件服务器(如Postfix)、认证服务(如Samba)等。通过LDAP,管理员可以集中管理用户账户,实现单点登录(Single Sign-On,SSO)功能,...

    ldap 浏览器 LdapBrowser282

    - **开发人员**:在开发 LDAP 集成的应用程序时,LdapBrowser282可以作为调试工具,帮助验证数据结构和查询逻辑。 - **故障排查**:当遇到 LDAP 相关的问题时,使用LdapBrowser282检查目录状态,定位问题源头。 ###...

    \Windows 2008 R2 域服务器web方式修改域用户密码

    1. **安装角色和角色服务**:首先,你需要在域控制器上安装"Web服务器(IIS)"角色,并添加"ASP.NET"和"轻量级目录访问(LDAP)身份验证"功能。 2. **部署Web应用程序**:下载并部署Microsoft的Web Password Reset(WPR...

    LDAP单点登录

    在IT行业中,LDAP被广泛应用于用户身份验证和权限管理,尤其是在大型企业或组织中,它能有效地统一管理用户的账号信息。而单点登录(Single Sign-On, SSO)则是一种让用户只需一次登录即可访问多个应用系统的技术,...

    LDAP使用手册

    通过深入学习这个"LDAP使用手册"和"Domino 同步视图设置",读者将能够理解 LDAP 的核心概念,掌握与 LDAP 服务器交互的编程技巧,并了解如何在实际环境中整合 LDAP 与 Lotus Domino。这些知识对于系统管理员、开发...

    LDAP基础教程

    3. **目录服务集成 (Directory Integration)**:整合企业内的各种系统,如HR、CRM和IT管理软件,实现信息同步。 五、学习资源 本教程提供的HTML文件可能包括以下内容: - "l-ldap.html" 可能是目录服务的基础概念...

    分布式会议系统(LDAP项目组)

    LDAP是一种开放的标准,用于存储和检索目录信息,如用户账号、组织结构、网络资源等。在分布式会议系统中,LDAP主要负责身份验证和授权。用户可以通过LDAP服务器进行登录,系统则会验证这些凭证并根据用户的权限...

    django使用LDAP验证的方法示例

    本文档详细介绍了如何在 Django 项目中集成 LDAP 身份验证,并提供了实际的配置示例和步骤指南。 #### 一、安装所需依赖 为了在 Django 应用中实现 LDAP 身份验证,首先需要安装两个必要的 Python 库: 1. **...

    ldap+samba

    在现代网络环境中,为了实现更加高效、便捷且安全的身份验证及资源访问控制机制,许多组织选择将Samba服务与LDAP(Lightweight Directory Access Protocol,轻量目录访问协议)进行集成。这种集成方式不仅能够简化...

    moodle 3.9集成windows AD用户设置说明

    在3.9版本中,Moodle支持与Windows Active Directory (AD)进行集成,使得用户可以直接使用AD账户登录,简化了用户的管理和认证流程。然而,由于官方文档的描述可能较为简洁,这里我们将深入探讨集成过程中的关键设置...

    禅道18.2开源版ldap插件

    通过集成ldap插件,禅道能够与企业已有的LDAP服务器进行交互,使得企业员工可以使用统一的账号登录禅道,无需为每个系统单独创建和管理密码。这对于大型组织来说,极大地提高了用户管理和安全性。 该插件的使用非常...

    Laravel开发-ldap-auth

    在 Laravel 框架中,LDAP(轻量级目录访问协议)认证是一种常见的企业级用户身份验证方法,它允许开发者将应用的用户登录功能与已存在的 LDAP 服务器集成,使得员工可以通过统一的企业账号系统登录应用。Laravel 的 ...

    针对 UNIX 的 Microsoft Windows 安全和目录服务解决方案指南

    - **跨平台集成**:通过 LDAP 与 AD 的交互,实现 UNIX 和 Windows 用户身份信息的共享和同步。 #### 第4章至第11章 接下来的章节将分别介绍: - **第4章**:构想异类安全和目录解决方案。 - **第5章**:规划异类...

    LDAP详解--IBM Tivoli Directory Server从入门到精通 源码

    IBM Tivoli Directory Server(TDS)是IBM提供的一个强大的、安全的企业级目录服务解决方案,它基于LDAP协议,用于存储和检索身份信息,如用户账号、组信息、网络资源位置等。通过TDS,企业可以集中管理其身份数据,...

Global site tag (gtag.js) - Google Analytics