精华内容
下载资源
问答
  • ldap组织结构数据同步到mysql 例子,将以下ldap人员结构图同步到mysql表中 mysql部门表和人员表,建表脚本,以及ldap服务连接信息 DROP TABLE IF EXISTS `sys_department`; CREATE TABLE `sys_department` ( ...

                              ldap组织结构数据同步到mysql

    例子,将以下ldap人员结构图同步到mysql表中

    mysql部门表和人员表,建表脚本,以及ldap服务连接信息

    DROP TABLE IF EXISTS `sys_department`;
    CREATE TABLE `sys_department`
    (
        `dept_id`     bigint(20)  NOT NULL AUTO_INCREMENT COMMENT '主键',
        `name`        varchar(20) NOT NULL COMMENT '部门名称',
        `parent_id`   bigint(20)  DEFAULT NULL COMMENT '父id',
        `strategy_id`   bigint(20)   DEFAULT NULL COMMENT '策略id',
        `level`       int         NULL COMMENT '层级',
        `state`       int(11)     NOT NULL DEFAULT '1' COMMENT '状态,0:禁用,1:启用',
        `sort`        int(11)     NOT NULL DEFAULT '0' COMMENT '排序',
        PRIMARY KEY (`dept_id`),
        UNIQUE KEY `name` (`name`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8mb4
      COLLATE = utf8mb4_general_ci COMMENT ='部门信息';
    
    DROP TABLE IF EXISTS `sys_user`;
    CREATE TABLE `sys_user`
    (
        `user_id`       bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '主键,用户id',
        `name`          varchar(20)  COMMENT '姓名',
        `user_name`      varchar(20) NOT NULL COMMENT '用户名',
        `phone`         varchar(20)  NOT NULL COMMENT '手机号码',
        `email`         varchar(100) NOT NULL COMMENT '邮箱',
        `strategy_id`   bigint(20)   COMMENT '策略id',
        `uid`          varchar(50)   COMMENT '虚拟机Uid',
        `login_time`     timestamp   NULL     DEFAULT CURRENT_TIMESTAMP COMMENT '最近登录时间',
        `remark`        varchar(200) COMMENT '备注',
        `dept_id`       bigint(20)   COMMENT '部门id',
        `password`      varchar(64)  DEFAULT NULL COMMENT '密码',
        `gender`        int(1)      DEFAULT NULL COMMENT '性别,0:女,1:男',
        `head`          varchar(200) DEFAULT null comment '头像',
        `role_id`       int(11)   DEFAULT NULL COMMENT '角色id',
        `deleted`       int(1)      DEFAULT NULL COMMENT '逻辑删除,0:未删除,1:已删除',
        `create_time`   timestamp    NULL     DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
        `update_time`   timestamp    NULL     DEFAULT NULL COMMENT '修改时间',
        `is_lock`       int(2)      DEFAULT 0 COMMENT '是否锁定,0:未锁定,1:已锁定',
        `is_default_password`    int(2)      DEFAULT 1 COMMENT '是否是默认密码,0:否,1:是',
        `is_use_role`   tinyint(1)   COMMENT '是否启用账户角色,0:停用,1,启用',
        `is_alarm_contact`  tinyint(1)   DEFAULT '0'  COMMENT '是否是告警联系人,0:否,1,是',
        `dingtalk_robot`   varchar(200)  COMMENT '钉钉机器人',
        PRIMARY KEY (`user_id`),
        UNIQUE KEY `user_name` (`user_name`),
        UNIQUE KEY `phone` (`phone`),
        UNIQUE KEY `email` (`email`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8mb4
      COLLATE = utf8mb4_general_ci COMMENT ='人员信息';
    
    DROP TABLE IF EXISTS `ldap`;
    CREATE TABLE `ldap` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `is_open`   tinyint(1)   DEFAULT '0'  COMMENT '状态,0:关闭,1:打开',
    `service_type` int(2) not null default 1  COMMENT '服务类型,1:openlaap,2:Microsoft Active Directory',
    `address`  varchar(200) not null  COMMENT '服务地址',
    `port`  varchar(20) not null  COMMENT '端口号',
    `user_name`  varchar(200) not null  COMMENT '用户名',
    `password`  varchar(30) not null  COMMENT '密码',
    `frequency`   int(11)   DEFAULT 1 COMMENT '同步频率',
    PRIMARY KEY (`id`)
    )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ldap服务连接信息';

    1.ldap接口,LdapAdapterEntityService类

    /**
     * ldap接口
     * 
     * @author begoit
     *
     */
    public interface LdapAdapterEntityService {
    
    	/**
    	 * 第三方向中间库添加组织机构 与 用户信息,用于数据同步
    	 */
    	@SuppressWarnings("rawtypes")
    	BaseResponse run();
    
    	/**
    	 * 组织机构更新方法入口
    	 * 
    	 * @param departMap
    	 */
    	void doUpdateDepatmentData(Map<String, Object> departMap);
    
    	/**
    	 * 用户更新方法入口
    	 * 
    	 * @param departMap
    	 */
    	void doUpdateUserData(Map<String, Object> departMap);
    }
    

    2.ldap 接口实现类,LdapAdapterEntityServiceImpl

    /**
     * ldap 接口实现类
     * 
     * @Component
     * @author begoit
     *
     */
    @Component
    @Slf4j
    public class LdapAdapterEntityServiceImpl implements LdapAdapterEntityService {
    
    	@Autowired
    	private LdapMapper ldapMapper;
    
    	@Autowired
    	private SysDepartmentMapper sysDepartmentMapper;
    
    	@Autowired
    	private SysUserMapper sysUserMapper;
    
    	@Autowired
    	private SysUserService sysUserService;
    
    	private String ldapUrl; // LDAP访问地址
    	private String ldapUser; // 用户名
    	private String ldapPwd; // 用户密码
    	private String ldapBasePath; // Base路径
    
    	private LdapContext ctx = null;
    
    	// private static boolean isRunning = false;
    
    	// 从 LDAP中读取 那些属性,具体属性查看LDAP数据
    	// String returnedGroupAtts[] = { "uSNCreated", "name" }; // 组织机信息构定制返回属性
    	String id = "ou";
    	String returnedGroupAtts[] = { id, "name" }; // 组织机信息构定制返回属性
    
    	// 用户信息定制返回属性,uSNCreated为id
    	// String returnedUserAtts[] = { "uSNCreated", "department", "name",
    	// "userPrincipalName", "mobile","distinguishedName", "employeeID" };
    	// String returnedUserAtts[] = { id, "userPrincipalName", "name",
    	// "userName", "phone", "email", "deptId" };
    	String returnedUserAtts[] = { id, "userPrincipalName", "cn", "sn", "telephoneNumber", "mail", "deptId" };
    
    	@SuppressWarnings({ "rawtypes" })
    	@Override
    	public BaseResponse run() {
    		BaseResponse response = new BaseResponse(StatusCode.Success);
    		/*
    		 * if (isRunning) { return; } isRunning = true;
    		 */
    		Ldap ldap = ldapMapper.selectLdap();
    		if (ldap == null) {
    			String msg = "没有设置ldap";
    			response.setstatus(500);
    			response.setmessage(msg);
    			log.error(msg);
    			return response;
    		}
    
    		if (!ldap.getIsOpen()) {// 如果是没打开
    			response.setmessage("ldap服务未启用");
    			return response;
    		}
    
    		ldapUrl = "ldap://" + ldap.getAddress() + ":" + ldap.getPort(); // ldap://10.10.16.226:389
    		ldapUser = ldap.getUserName(); // cn=admin,dc=cpu-os,dc=com
    		ldapPwd = ldap.getPassword(); // pass123456
    		ldapBasePath = getLdapBasePath(ldapUser); // dc=cpu-os,dc=com
    
    		// 初始化LDAP 目录服务上下文 获取信息 添加到集合中
    		Hashtable<String, String> HashEnv = new Hashtable<String, String>();
    		// 验证ad域
    		HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
    		HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
    		HashEnv.put(Context.SECURITY_PRINCIPAL, ldapUser); // AD User
    		HashEnv.put(Context.SECURITY_CREDENTIALS, ldapPwd); // AD Password
    		HashEnv.put(Context.PROVIDER_URL, ldapUrl);
    		try {
    			log.info("[" + new Date().toString() + "][LDAP]------------------------begin--------------------------");
    			// 1.2 构造一个初始上下文使用环境属性和连接请求控制
    			ctx = new InitialLdapContext(HashEnv, null);
    
    			// 同步机构
    			setGroupToAMS();
    			log.info("[" + new Date().toString() + "][LDAP]------------------------end--------------------------");
    		} catch (Exception e) {
    			String msg = "同步Ldap出错," + e.getMessage();
    			response.setstatus(500);
    			response.setmessage(msg);
    			log.error(msg);
    		} finally {
    			try {
    				if (ctx != null) {
    					ctx.close();// 关闭连接
    					ctx = null;
    				}
    			} catch (NamingException e) {
    				String msg = "同步Ldap出错," + e.getMessage();
    				response.setstatus(500);
    				response.setmessage(msg);
    				log.error(msg);
    			}
    
    		}
    		return response;
    	}
    
    	/**
    	 * 同步
    	 * 
    	 * @throws NamingException
    	 */
    	public void setGroupToAMS() throws NamingException {
    		// 机构同步
    		setGroupToAMS(ldapBasePath, "0");
    	}
    
    	/**
    	 * 获取Ldap的BasePath
    	 * 
    	 * @param ldapUser
    	 * @return
    	 */
    	public String getLdapBasePath(String ldapUser) {
    		if (StringUtils.isEmpty(ldapUser)) {
    			return StringUtils.EMPTY;
    		}
    		String[] ldapUsers = ldapUser.split(",");
    		if (ldapUsers != null && ldapUsers.length >= 2) {
    			String ldapBasePath = ldapUsers[ldapUsers.length - 2] + "," + ldapUsers[ldapUsers.length - 1];
    			return ldapBasePath;
    		} else {
    			return StringUtils.EMPTY;
    		}
    
    	}
    
    	/**
    	 * 递归机构同步
    	 * 
    	 * @param groupName
    	 *            机构名称与地址
    	 * @param parentorgid
    	 *            机构父ID
    	 * @throws NamingException
    	 */
    	public void setGroupToAMS(String groupName, String parentorgid) throws NamingException {
    		// 设置过滤条件 : objectclass 为 organizationalUnit 的数据 ,即,只查机构数据
    		String searchFilter = "objectclass=organizationalUnit";
    
    		// Create the search controls 查询条件
    		SearchControls searchCtls = new SearchControls();
    
    		// Specify the search scope , 仅查询一级信息
    		searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    
    		// 设置查询返回属性集
    		searchCtls.setReturningAttributes(returnedGroupAtts);
    
    		// 执行查询
    		NamingEnumeration<SearchResult> answer = ctx.search(groupName, searchFilter, searchCtls);
    
    		// 迭代返回结果
    		while (answer.hasMoreElements()) {
    			SearchResult sr = (SearchResult) answer.next();
    
    			// 本级的组织机构 OU
    			String orgName = sr.getName() == null ? "" : sr.getName().trim();
    			if (orgName.equals(""))
    				continue;
    			Attributes Attrs = sr.getAttributes();
    
    			// 声明map 接收组织机构信息
    			Map<String, Object> groupInfoMap = new HashMap<String, Object>();
    
    			// 添加组织机构父ID
    			// groupInfoMap.put("groupPid", parentorgid);
    			groupInfoMap.put("parentId", parentorgid);
    			if (Attrs != null) {
    				try {
    					for (NamingEnumeration<? extends Attribute> ne = Attrs.getAll(); ne.hasMore();) {
    						Attribute Attr = (Attribute) ne.next();
    						// 读取属性 KEY
    						String attrName = Attr.getID().toString();
    						String value = null;
    						// 读取属性 VALUE
    						for (NamingEnumeration<?> e = Attr.getAll(); e.hasMore();) {
    							value = e.next().toString();
    						}
    						groupInfoMap.put(attrName, value);
    					}
    					log.info("同步机构名称 == " + groupInfoMap);
    					doUpdateDepatmentData(groupInfoMap);
    					if (ObjectUtils.isEmpty(groupInfoMap.get(id))) {
    						break;
    					}
    					/** 递归同步下级机构 **/
    					// setGroupToAMS(orgName + "," + groupName,
    					// groupInfoMap.get(id).toString());
    					SysDepartment sysDepartment = sysDepartmentMapper.selectByName(groupInfoMap.get(id).toString());
    					parentorgid = sysDepartment.getDeptId().toString();
    					setGroupToAMS(orgName + "," + groupName, parentorgid);
    					setUserToAMS(orgName + "," + groupName, parentorgid);
    				} catch (NamingException e) {
    					log.error("同步ldap,递归机构同步失败:{}", e.getMessage());
    				}
    			}
    		}
    	}
    
    	/**
    	 * 同步用户信息
    	 * 
    	 * @param groupName
    	 * @param departmentId
    	 * @throws NamingException
    	 */
    	public void setUserToAMS(String groupName, String departmentId) throws NamingException {
    		String searchFilter = "objectclass=organizationalPerson";
    		SearchControls searchCtls = new SearchControls(); // Create the search
    															// controls
    		searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE); // Specify the
    																	// search
    																	// scope
    		searchCtls.setReturningAttributes(returnedUserAtts); // 设置返回属性集
    		NamingEnumeration<SearchResult> answer = ctx.search(groupName, searchFilter, searchCtls);
    		while (answer.hasMoreElements()) {
    			SearchResult sr = (SearchResult) answer.next();
    			String userName = sr.getName() == null ? "" : sr.getName().trim();
    			if (userName.equals(""))
    				continue;
    			Attributes Attrs = sr.getAttributes();
    			Map<String, Object> userInfoMap = new HashMap<String, Object>();
    			// 添加用户组织机构
    			// userInfoMap.put("org_id", departmentId);
    			// userInfoMap.put("deptId", departmentId);
    			userInfoMap.put("deptId", departmentId);
    			if (Attrs != null) {
    				try {
    					for (NamingEnumeration<? extends Attribute> ne = Attrs.getAll(); ne.hasMore();) {
    						Attribute Attr = (Attribute) ne.next();
    						String attrName = Attr.getID().toString();
    						String value = null;
    						for (NamingEnumeration<?> e = Attr.getAll(); e.hasMore();) {
    							value = e.next().toString();
    							userInfoMap.put(attrName, value);
    							// 如果是 userPrincipalName 截取 并添加到 LOGON_NAME
    							// 中,即从邮件中截取登陆名
    							if ("userPrincipalName".equals(attrName)) {
    								userInfoMap.put("logon_name", value.split("@")[0]);
    							}
    						}
    						userInfoMap.put(attrName, value);
    					}
    					doUpdateUserData(userInfoMap);
    				} catch (NamingException e) {
    					log.error("同步ldap,同步用户失败:{}", e.getMessage());
    				}
    			}
    		}
    	}
    
    	/**
    	 * 更新部门表数据
    	 */
    	@Override
    	public void doUpdateDepatmentData(Map<String, Object> departMap) {
    		// 判断 Map 是否为空
    		if (null != departMap) {
    			// 取 KEY : uSNCreated
    			String deptName = CommomUtils.object2String(departMap.get(id));
    
    			if (StringUtils.isEmpty(deptName)) {
    				return;
    			}
    
    			SysDepartment sysDepartmentDb = sysDepartmentMapper.selectByName(deptName);
    
    			SysDepartment sysDepartment = this.mapToSysDepartment(departMap);
    
    			// 存在 执行更新
    			if (sysDepartmentDb != null) {
    				// sysDepartmentMapper.updateByPrimaryKeySelective(sysDepartment);
    				sysDepartmentMapper.updateByNameSelective(sysDepartment);
    			} else {
    				// 不存在执行 新增
    				sysDepartmentMapper.insertSelective(sysDepartment);
    			}
    
    		}
    	}
    
    	/**
    	 * map转SysDepartment
    	 * 
    	 * @param departMap
    	 * @return
    	 */
    	private SysDepartment mapToSysDepartment(Map<String, Object> departMap) {
    		SysDepartment sysDepartment = new SysDepartment();
    		// sysDepartment.setDeptId(CommomUtils.object2Long(departMap.get(id)));
    		sysDepartment.setName(CommomUtils.object2String(departMap.get(id)));
    		sysDepartment.setParentId(CommomUtils.object2Long(departMap.get("parentId")));
    		return sysDepartment;
    	}
    
    	/**
    	 * map转SysUser
    	 * 
    	 * @param departMap
    	 * @return
    	 */
    	private SysUser mapToSysUser(Map<String, Object> userMap) {
    		SysUser sysUser = new SysUser();
    		/*
    		 * sysUser.setUserId(CommomUtils.object2Long(userMap.get(id)));
    		 * sysUser.setName(CommomUtils.object2String(userMap.get("name")));
    		 * sysUser.setUserName(CommomUtils.object2String(userMap.get("userName")
    		 * ));
    		 * sysUser.setPhone(CommomUtils.object2String(userMap.get("phone")));
    		 * sysUser.setEmail(CommomUtils.object2String(userMap.get("email")));
    		 * sysUser.setDeptId(CommomUtils.object2Long(userMap.get("deptId")));
    		 */
    		sysUser.setUserId(CommomUtils.object2Long(userMap.get(id)));
    		sysUser.setName(CommomUtils.object2String(userMap.get("cn")));
    		sysUser.setUserName(CommomUtils.object2String(userMap.get("sn")));
    		sysUser.setPhone(CommomUtils.object2String(userMap.get("telephoneNumber")));
    		sysUser.setEmail(CommomUtils.object2String(userMap.get("email")));
    		sysUser.setDeptId(CommomUtils.object2Long(userMap.get("deptId")));
    		return sysUser;
    	}
    
    	/**
    	 * SysUser 转 SysUserDto
    	 * 
    	 * @param departMap
    	 * @return
    	 */
    	private SysUserDto sysUserToSysUserDto(SysUser sysUser) {
    		SysUserDto sysUserDto = new SysUserDto();
    		sysUserDto.setName(sysUser.getName());
    		sysUserDto.setUserName(sysUser.getUserName());
    		sysUserDto.setPhone(sysUser.getPhone());
    		sysUserDto.setEmail(sysUser.getEmail());
    		sysUserDto.setDeptId(sysUser.getDeptId());
    		return sysUserDto;
    	}
    
    	/**
    	 * 更新用户表数据
    	 */
    	@Override
    	public void doUpdateUserData(Map<String, Object> userMap) {
    		if (null != userMap) {
    			/*
    			 * String userId = (userMap.get(id) == null ||
    			 * !"".equals(userMap.get(id))) ? userMap.get(id).toString() : "0";
    			 */
    			SysUser sysUser = this.mapToSysUser(userMap);
    			if (StringUtils.isBlank(sysUser.getUserName())) {
    				return;
    			}
    			if (StringUtils.isBlank(sysUser.getPhone())) {
    				sysUser.setPhone(("改") + UIDUtil.nextLongId(11));
    			}
    			if (StringUtils.isBlank(sysUser.getEmail())) {
    				sysUser.setEmail(("改") + UIDUtil.nextLongId(10) + "@qq.com");
    			}
    			// SysUser sysUserDb =
    			// sysUserMapper.selectByPrimaryKey(sysUser.getUserId());
    			SysUser sysUserDb = sysUserMapper.selectByUserName(sysUser.getUserName());
    			if (sysUserDb != null) {
    				try {
    					sysUserMapper.updateByPrimaryKeySelective(sysUser);
    				} catch (Exception e) {
    					String msg = "邮件或者电话号已被其它用户占用";
    				}
    			} else {
    				SysUserDto sysUserDto = this.sysUserToSysUserDto(sysUser);
    				// 添加人员
    				BaseResponse response = sysUserService.addSysUser(sysUserDto);
    			}
    		}
    	}
    
    	/**
    	 * 增加一个组织结构
    	 * 
    	 * @throws NamingException
    	 */
    	public void createNode() throws NamingException {
    		Attributes attr = new BasicAttributes();
    		BasicAttribute ocattr = new BasicAttribute("objectclass");
    		ocattr.add("organizationalUnit");
    		ocattr.add("top");
    		attr.put(ocattr);
    		// ctx.rebind("ou=业务, dc=cpu-os, dc=com", null, attr);
    		// ctx.rebind("ou=事业部, ou=业务, dc=cpu-os, dc=com", null, attr);
    		// ctx.rebind("ou=项目组,ou=事业部, ou=业务, dc=cpu-os, dc=com", null, attr);
    		// ctx.bind("ou=会计组,ou=项目组,ou=事业部, ou=业务, dc=cpu-os, dc=com", null,
    		// attr);
    
    		NamingEnumeration<SearchResult> answer = ctx.search("ou=营销部, ou=业务, dc=cpu-os, dc=com", attr);
    		if (answer != null) {
    			while (answer.hasMore()) {
    
    				SearchResult sr = (SearchResult) answer.next();
    
    				log.info("-------------------->>>" + sr.getName());
    
    				log.info(sr.getAttributes().toString());
    
    			}
    
    		} else {
    			ctx.bind("ou=营销部, ou=业务, dc=cpu-os, dc=com", null, attr);
    		}
    
    	}
    
    	/**
    	 * 增加一个组织结构
    	 * 
    	 * @throws NamingException
    	 */
    	public void createU() throws NamingException {
    		Attributes attr = new BasicAttributes();
    		BasicAttribute ocattr = new BasicAttribute("objectclass");
    		// ocattr.add("user");
    		ocattr.add("top");
    		ocattr.add("organizationalPerson");
    		ocattr.add("shadowAccount");
    		// ocattr.add("person");
    		attr.put(ocattr);
    		// attr.put("userPassword", "12");
    		attr.put("sn", "zhaoqi");
    		attr.put("uid", UIDUtil.getUUID());
    		// attr.put("userName", "zhangsan");
    		// attr.put("userPrincipalName","userPrincipalNametest");
    		// attr.put("name","nametest");
    		// attr.put("email", "zhuinfo@163.com");
    		// attr.put("deptId","deptIdtest");
    		// attr.put("id","1234568");
    		attr.put("telephoneNumber", "13203142019");
    		/*
    		 * BasicAttribute emailAttr = new BasicAttribute("email");
    		 * 
    		 * 
    		 * emailAttr.add("892531764@qq.com"); attr.put(emailAttr);
    		 */
    		// attr.put(new BasicAttribute("mail","892531764@qq.com"));
    
    		// ldapTemplate.bind("ou=IT", null, attr);// buildDN() function
    		// ctx.bind("cn=赵六,ou=营销部, ou=业务, dc=cpu-os, dc=com", null, attr);
    		NamingEnumeration<SearchResult> answer = ctx.search("cn=赵七,ou=营销部, ou=业务, dc=cpu-os, dc=com", attr);
    		if (answer != null) {
    			ctx.modifyAttributes("cn=赵七,ou=营销部, ou=业务, dc=cpu-os, dc=com", DirContext.REPLACE_ATTRIBUTE, attr);
    		} else {
    			ctx.bind("cn=赵七,ou=营销部, ou=业务, dc=cpu-os, dc=com", null, attr);
    		}
    
    		// ctx.modifyAttributes("cn=赵四,ou=营销部, ou=业务, dc=cpu-os, dc=com",
    		// DirContext.REPLACE_ATTRIBUTE, attr);
    
    	}
    
    	@SuppressWarnings({ "rawtypes" })
    	public BaseResponse Test() {
    		BaseResponse response = new BaseResponse(StatusCode.Success);
    		/*
    		 * if (isRunning) { return; } isRunning = true;
    		 */
    		Ldap ldap = ldapMapper.selectLdap();
    		if (ldap == null) {
    			String msg = "没有设置ldap";
    			response.setstatus(500);
    			response.setmessage(msg);
    			log.error(msg);
    			return response;
    		}
    
    		if (!ldap.getIsOpen()) {// 如果是没打开
    			response.setmessage("ldap服务未启用");
    			return response;
    		}
    
    		ldapUrl = "ldap://" + ldap.getAddress() + ":" + ldap.getPort(); // ldap://10.10.16.226:389
    		ldapUser = ldap.getUserName(); // cn=admin,dc=cpu-os,dc=com
    		ldapPwd = ldap.getPassword(); // pass123456
    		ldapBasePath = getLdapBasePath(ldapUser); // dc=cpu-os,dc=com
    
    		// 初始化LDAP 目录服务上下文 获取信息 添加到集合中
    		Hashtable<String, String> HashEnv = new Hashtable<String, String>();
    		// 验证ad域
    		HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别
    		HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
    		HashEnv.put(Context.SECURITY_PRINCIPAL, ldapUser); // AD User
    		HashEnv.put(Context.SECURITY_CREDENTIALS, ldapPwd); // AD Password
    		HashEnv.put(Context.PROVIDER_URL, ldapUrl);
    		try {
    			log.info(
    					"[" + new Date().toString() + "][LDAP]------------------------begin------------test--------------");
    			// 1.2 构造一个初始上下文使用环境属性和连接请求控制
    			ctx = new InitialLdapContext(HashEnv, null);
    
    			createNode();
    			createU();
    			log.info("[" + new Date().toString() + "][LDAP]------------------------end---------------test-----------");
    		} catch (Exception e) {
    			String msg = "同步Ldap出错," + e.getMessage();
    			response.setstatus(500);
    			response.setmessage(msg);
    			log.error(msg);
    		} finally {
    			try {
    				if (ctx != null) {
    					ctx.close();// 关闭连接
    					ctx = null;
    				}
    			} catch (NamingException e) {
    				String msg = "同步Ldap出错," + e.getMessage();
    				response.setstatus(500);
    				response.setmessage(msg);
    				log.error(msg);
    			}
    
    		}
    		return response;
    	}
    
    }

    3.LdapController

    /**
    	 * 同步Ldap数据
    	 * 
    	 * @param connectLdapDto
    	 * @return
    	 */
    	@SuppressWarnings({ "rawtypes" })
    	@PostMapping("/s/ldap/syncLdapData")
    	public BaseResponse sync() {
    		BaseResponse response = ldapAdapterEntityServiceImpl.run();
    		return response;
    	}

    同步的结果:

     

    展开全文
  • LDAP数据结构

    2011-10-18 22:41:29
    LDAP数据结构 标准键 值 描述 o gbit 组织 organization的单词首字母 ou db center 组织单位 organization unit的两个单词首字母 l amoy fujian china 城市/所在地(location) uid ...

    LDAP的数据结构

    标准键 描述
    o gbit 组织 organization的单词首字母
    ou db center 组织单位 organization unit的两个单词首字母
    l amoy fujian china 城市/所在地(location)
    uid linzq 用户名。应该是用到验证的用户名,与我们在数据库中用于登陆的用户名一样。
    c zh-cn 国家(country)
    cn 林忠青 用户全名
    sn 用户名中的姓
    st available 状态,用户的使用状态(status)
    givenName 忠青 用户名中的名字
    employeeNumber A445 员工编号
    employeeType   员工类型
    description   描述
    mail linzq@gbit.com 邮箱地址
    telephoneNumber 13799265585 电话
    facsimileTelephoneNumber   传真号码
    mobile   移动电话号码
    pager   寻呼机号码
    photo   相片(应该是存放相片的字节流)
    postalAddress   邮政地址
    postalCode   邮政编码
    homePhone   住宅电话号码
    roomNumber   门牌号
    preferredLanguage zh-cn 母语
    street   街道地址
    entryDN cn=林忠青,dc=example,dc=com 唯一标识
    entryUUID b2d07f19-0214-425b-a652-409a84ed9ac4 全局ID值
    userPassword e1NTSEF9aXUwSlNPWEEzejRBQlhOemd
    0Q3NDaXdENUh1cmo4Y2labTBzeWc9PQ==
    用户密码
    展开全文
  • 了解LDAP协议、数据结构与条目组件

    千次阅读 2017-04-17 09:40:35
    提供:ZStack云计算 内容介绍LDAP, 全称为轻量级目录访问协议,是一项开放协议,用于通过分层目录结构数据进行存储与检索。LDAP是一种灵活的解决方案,适用于定义各类条目及相关性质。对大多数用户而言,LDAP似乎...

    提供:ZStack云计算

    内容介绍

    LDAP, 全称为轻量级目录访问协议,是一项开放协议,用于通过分层目录结构对数据进行存储与检索。LDAP是一种灵活的解决方案,适用于定义各类条目及相关性质。

    对大多数用户而言,LDAP似乎难于理解——因为其使用专项术语,采用多种不太常见的缩写,且常常作为大型组件交互系统中的组成部分使用。在本教程中,我们将介绍LDAP基础概念,帮助大家顺利上手这套方案。

    目录服务是什么?

    目录服务用于通过键-值类型格式存储、整理及表达数据。一般来讲,目录会面向查找、搜索以及读取操作做出优化,因此适用于经常引用但却较少变更的数据。

    存储在目录服务中的数据通常根据特性加以描述,并用于定义某条目的性质。以通讯簿为例,每个人都能够以一个条目的方式在目录中表现,由键-值对描述其通讯信息、业务范围等。目录服务适用于各类需要进行定性的描述性信息。

    LDAP是什么?

    LDAP,全称为轻量级目录访问协议,是一项用于定义目录服务访问方法的通信协议。总体来讲,LDAP能够定义数据在目录服务内如何呈现给用户,定义目录服务内各用于创建数据条目的组件,同时概述组成条目的不同基本元素。

    由于LDAP是一项开放协议,因此其拥有多种实现方式。OpenLDAP项目正是其中广受支持的开源衍生成果。

    基本LDAP数据组件

    LDAP向用户显示数据的方式多种多样,具体取决于所定义结构组件之间的交互与关系,因此其复杂程度相当之高。

    属性

    LDAP系统中的数据主要以被称为属性的元素形式存储。属性在本质上属于键-值对。与其它系统不同,其中的键名称由为条目选定的objectClasses进行预定义。另外,属性中的数据必须匹配属性初始定义内所定义的类型。

    要为属性设定值,我们需要为其提供属性名称与属性值,二者以逗号加一个空格隔开。以下示例为名为mail且负责定义邮箱地址的属性:

    mail: admin@example.com
    

    在引用属性及其数据(非设定时)时,注意使用等号:

    mail=example.com
    

    该属性值包含我们需要在LDAP系统中存储并访问的大部分实际数据。LDAP中的其它元素则用于表达结构与组织等等。

    条目

    单凭属性本身没有多少作用,我们必须将其与其它事物进行关联。在LDAP中,我们在条目内使用属性。条目基本上相当于属性与一条用于描述事物的名称的集合。

    例如,大家可以在系统为一位用户设置一个条目,或者在库存目录中为每项目设置条目。这类似于关系数据库系统中的一行或者通讯簿中的一页。属性定义的是一条性质或者特征,而条目则通过属性于名称的结合描述项目本身。

    LDIF(即LDAP数据交换格式)内的条目示例如下:

    dn: sn=Ellingwood,ou=people,dc=digitalocean,dc=com
    objectclass: person
    sn: Ellingwood
    cn: Justin Ellingwood
    

    以上即为LDAP系统中的一条有效条目。

    DIT

    熟悉了LDAP之后,大家会发现属性所定义的数据只代表某一对象的一部分可用信息。其余部分则存在于LDAP当中,即其相互关系。

    例如,如果我们可以为一个用户与一个库存项目设置条目,那么人们该如何对二者加以区分?一种方式就是建立关系与组。条目在创建之时即拥有这一功能,而条目则会被添加至LDAP系统当中充当分支或者树,即数据信息树,简称DIT。

    DIT代表的是与文件系统类似的一种组织化结构,其中每个条目(除了顶级条目)有且只有一个父条目,其下则可能拥有任意数量子条目。因此,LDAP树内的各条目可以代表任何事物,其中部分条目将被主要用于组织用途,类似于文件系统内的目录。

    如此一来,大家就能够为“人员”创建一个条目,再为“库存项目”创建一个条目。大家的实际数据条目可以作为二者之下的子条目存在。另外,各组织型条目可以随意定义为最理想的数据代表方式。

    在上一章节的示例条目,我们可以看到dn行中的DIT表现:

    dn: sn=Ellingwood,ou=people,dc=digitalocean,dc=com
    

    此行被称为该条目的专有名称,用于指定条目身份。其作用类似于指向DIT root的完整路径。在本示例中,我们的条目名为sn=Ellingwood,而其直接父条目则为ou=people,其可能用于容纳负责描述人员的各相关条目此条目的各父条目衍生自digitalocean.com域名,其作为我们DIT的root存在。

    定义LDAP数据组件

    在上一节,我们探讨了数据如何在LDAP系统中加以表现。然而,我们还需要讨论负责存储数据的各组件的定义方式。例如,我们提到数据必须与每条属性的定义类型相匹配。这些定义来自哪里?下面我们从底层开始,一步步加以讲解。

    属性定义

    属性利用相当复杂的语法进行定义。其必须注明属性名称、任何其它能够用于引用该属性的名称、可以输入的数据类型以及其它各类元数据。该元数据能够描述此属性,告知LDAP如何对属性值进行排序或比对,同时告知其如何将其与其它属性相关联。

    例如,以下为name属性的定义:

    attributetype ( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name attributes'
        EQUALITY caseIgnoreMatch
        SUBSTR caseIgnoreSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
    

    其中“name”为属性的名称。第一行中的数字为全局惟一OID(即对象ID),被分配至该属性以将其同其它属性区分开来。条目中的其它内容则定义该条目在搜索中如何实现比对,另有一个指针告知属性的数据类型要求应在哪里找到信息。

    属性定义中的一大要点在于,该属性是否能够在条目中进行多次定义。例如,定义可能要求每个姓氏只能在各条目中被定义一次,但“侄女”的属性则允许该属性在单一条目中被定义多次。属性在默认情况下可包含多个值,且如果在单一条目中只能被定义一次,则必须以SINGLE-VALUE加以标记。

    属性定义要比属性的使用与设定更为复杂。幸运的是,大多数情况下我们无需自行定义属性,因为大部分LDAP实现方案中已经提供各类最为常用的属性,其它方案亦能够轻松导入现成属性。

    ObjectClass定义

    各属性被收集在objectClasses条目当中。ObjectClasses属于相关属性的简单分组,可用于描述特定事物。例如,“个人”就属于一个objectClass。

    条目能够通过设置一条objectClass特殊属性的方式使用objectClass的属性,当然大家也可以使用任何其它objectClass。事实上,objectClass是我们在条目中无需进一步指定objectClass即能够设置的惟一属性。

    因此,如果大家打算创建一个条目以描述某个人,那么添加objectClass person(或者任何特定个人)即可使用该objectClss中的全部属性:

    dn: . . .
    objectClass: person
    

    大家可以在该条目中设定以下属性:

    • cn: 通用名称
    • description: 人类可阅读的条目描述
    • seeAlso: 引用相关条目
    • sn: 姓氏
    • telephoneNumber: 一条电话号码
    • userPassword: 一条用户密码

    如果大家需要使用来自其它objectClasses的属性,则可多次使用objectClass属性,但需要遵循相关接纳规则。ObjectClasses被定义为多种“类型”之一。

    ObjectClasses的两大主要类型为结构型与辅助型。单一条目必须拥有单一结构类,但可能不具备或者具备多个结构类(用于为该类提供可用属性)。结构型objectClass则用于创建及定义该条目,而辅助型objectClasses则通过额外添加为其提供附加功能。

    ObjectClass定义会检测其提供的各属性是否必要(由MUST规范指示)或者属于可靠锭(由MAY规范指示)。多个objectClasses能够提供同样的属性,而单一属性的MAY或者MUST分类可能在不同objectClasses之间有所区别。

    例如,person objectClass定义如下:

    objectclass ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL
      MUST ( sn $ cn )
      MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
    

    其被定义为一个结构型objectClass,意味着其可用于创建一个条目。此创建的条目必须设定surname与commonname属性,且可选设定userPassword、telephoneNumber、seeAlso或者description属性。

    Schemas

    ObjectClass定义与属性定义二者由一套架构组合在一起,这就是schema。与传统关系数据库不同,LDAP中的schemas单纯收集相关objectClasses与属性。单一DIT能够包含多个不同schemas,因此其可以创建需要的条目与属性。

    Schemas通常包含额外的属性定义且可能要求该属性在其它schemas中定义。例如,我们之前提到的person objectClass就要求利用person objectClass为任意条目设定surname或者snattribute。如果其在LDAP服务器内部未经定义,则包含有这些定义的schema可用于将这些定义添加至服务器词汇。

    Schema格式基本上属于以上条目的结合,例如:

    . . .
    
    objectclass ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCTURAL
      MUST ( sn $ cn )
      MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
    
    attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' )
      DESC 'RFC2256: last (family) name(s) for which the entity is known by' SUP name )
    
    attributetype ( 2.5.4.4 NAME ( 'cn' 'commonName' )
      DESC 'RFC4519: common name(s) for which the entity is known by' SUP name )
    
    . . .
    

    数据组织

    我们已经探讨了LDAP系统内用于构建条目的常见元素,亦谈到了这些组成部分如何在系统中进行定义。然而,我们还没有提到信息自身如何组织并在LDAP DIT中建立结构。

    在DIT中安置条目

    一条DIT单纯属于描述现有条目间关系的层次结构。在创建之后,每个新条目都必须“钩入”现有DIT,即将自身作为现有条目的一个子条目。这会建立起一套树状结构,用于定义关系并分配含义。

    DIT的顶端为最广泛的范畴,其下则属于某种方式的后代。通常情况下,顶端条目作为标签指明DIT所使用的组织。这些条目可以根据objectClasses的需要进行任意调整,但一般其会利用哉组件(与example.com的LDAP管理信息相关的为dc=example,dc=com)、位置(位于纽约的组织或者分区为l=new_york,c=us)或者组织型分区(ou=mrketing,o=Example_Co)进行构建。

    组织所使用的条目(使用方式与文件夹类似)通常使用组织型Unit objectClass,其允许使用名为ou=的简单描述性属性标签。其通常用于顶端DIT条目(例如ou=people,ou=groups以及ou=inventory)的常规分类。LDAP专门针对遵循树状结构进行信息查找做出优化,因此往往最适合保留DIT结构,其中通过特定属性分配表明其进一步细分方式。

    在DIT内命名并引用条目

    我们根据属性进行条目引用。这意味着每个条目必须拥有一条或者一组属性,其在DIT层次中拥有明确的等级。此属性或者属性组被称为该条目的相对可分辨名称,或者简称RDN,其功能与文件名称类似。

    要明确引用栽个条目,大家可以使用该条目的RDN同时结合其父条目的全部RDN。这条RDN锭会逐步引导回DIT层次顶端,并为查询的条目提供一条明确路径。我们将这条RDN链称为条目的专有名称,或者简称DN。大家必须在创建过程中为条目指定该DN,这样LDAP系统才能知晓在哪里安置新条目,同时确保该条目的RDN不会为其它现有条目所使用。

    打个比方,大家可以将RDN看作是文件或者目录名。另一方面,DN则更像是路径。不过一大重要区别在于,LDAP DN将大部分特定值容纳在左侧,而文件路径则将大部分特定信息容纳于右侧。DN将RDN各值以逗号分隔。

    例如,一个面向John Smith的条目可能被放置于“人员”条目之下,后者则充当example.com的组织。由于该组织内可能存在多位John Smiths,因此我们最好使用用户ID作为该条目的RDN。该条目如下所示:

    dn: uid=jsmith1,ou=People,dc=example,dc=com
    objectClass: inetOrgPerson
    cn: John Smith
    sn: Smith
    uid: jsmith1
    

    我们需要使用inetOrgPerson objectClass以访问此实例中的uid属性(我们也拥有该person objectClass内所定义的全部属性的访问能力,接下来将进一步说明)。

    LDAP继承

    在实际应用当中,LDAP系统中的大多数数据彼此关联为层次、继承与嵌套。LDAP之所以不为大家所熟悉,很大程度上是因为其在设计中采用了部分面向对象概念。这一点主要体现在类的使用方面,外加层次的存在——而这正是本部分的核心内容。

    ObjectClass继承

    每个objectClass都是一个类,负责描述该类型对象的特征。

    不过与简单的层次机制不同,LDAP中的对象能够且通常为多个类实例(部分编程语言利用多层次提供类似的功能)。这是因为LDAP的类概念单纯只是一个其MUST或者MAY具备的属性的集合。这意味着单一条目能够拥有多个类(尽管其中只有一个结构型objectClass能够且必须得以表达),结果就是该对象中利用严格的MUST或者MAY声明对合并后的属性集合加以访问。

    在定义当中,objectClass能够指定一个父objectClass,并经由后者继承其属性。具体用法为在objectClass后面使用SUP来指定继承自何处。例如,organizationalPerson objectClass为:

    objectclass ( 2.5.6.7 NAME 'organizationalPerson' SUP person STRUCTURAL
     . . .
    

    该objectClass后的SUP标识符指明其父objectClass。该父类必须共享该objectClass所定义的objectClass类型(例如结构型或者辅助型)。子objectClass会自动继承该父类的属性与属性要求。

    在条目中分配objectClass时,大家只需要为某继承链中最为具体的后代指定为可访问全部上层属性即可。在上一节中,我们利用这种方式将inetOrgPerson作为惟一objectClass指定至我们的John Smith条目,但同时仍保留了person与organizationlPerson objectClasses中所定义属性的访问能力。其中inetOrgPerson继承层次如下所示:

    inetOrgPerson -&gt; organizationalPerson -&gt; person -&gt; top
    

    几乎全部objectClass继承树都会以名为“top”的特殊objectClass作为结尾。这是一个抽象objectClass,其惟一作用就是要求objectClass自身处于设置完成状态。它用于指定该继承链的顶部。

    属性继承

    属性也能够在定义过程中以类似的方式列举一项父属性。该属性随后将继承父属性中所设置的各项属性。

    其通常用于为某项通用属性生成更为具体的版本。例如,surname为一种名称类型,且可使用与相同的方法实现特性比对与检查。它能够继承这些特性以获得“name”属性的通用形式。事实上,具体surname定义可能仅包含一个回指至父属性的指针。

    通过这种方式,我们能够创建一条特定属性,从而帮助人们解释该元素,且其通用形式仍然不受影响。我们在这里谈到的surname属性,其继承机制就能帮助人员区分姓氏与普通姓名,但除了值的含义不同之外,姓氏与名称对于LDAP系统而言几乎没有区别。

    LDAP协议的衍生版本

    我们在文章开头提到,LDAP代表的是一套定义通信接口以实现目录服务协作的协议。我们通常将其称为LDAP或者ldap协议。

    不过需要强调的是,在常规形式之外其还拥有多个衍生版本:

    • ldap://: 一项基本LDAP协议,允许对目录服务进行结构化访问。
    • ldaps://: 此衍生版本用于通过SSL/TLS实现LDAP表达。普通LDAP流量未经加密,不过大多数LDAP实现方案支持此功能。这种LDAP连接加密方法实际已经被弃用,建议大家使用STARTTLS作为替代。如果大家在非安全网络上使用LDAP,则强烈建议使用加密机制。
    • ldapi://: 用于通过IPC表达LDAP。其通常用于安全接入本地LDAP系统以实现管理用途。其能够内部嵌套而非公开网络端口实现通信。

    这三种格式皆使用LDAP协议,但后两种使用额外专有信息指定其使用方式。

    总结

    到这里,大家应该已经理解了LDAP协议以及如何利用LDAP向用户表达数据。另外,我们也探讨了该系统中的各元素如何彼此关联,其在哪里实现属性管理以及怎样以更轻松且更具预测性的方式使用LDAP系统。

    本文来源自DigitalOcean Community。英文原文:Understanding the LDAP Protocol, Data Hierarchy, and Entry Components By Justin Ellingwood

    翻译:diradw

    展开全文
  • 使用字母和数字的变形,通过结构LDAP 数据创建有用的向量空间。并且显示与每个输入查询最适当的匹配,同时自动修正印刷错误和拼写错误。 介绍向量空间搜索的文章通常都从介绍向量空间并说明如何将指定查询投射到...
    使用 Perl 和向量空间搜索引擎搜索和显示轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP)数据库中的记录。使用字母和数字的变形,通过结构化 LDAP 数据创建有用的向量空间。并且显示与每个输入查询最适当的匹配,同时自动修正印刷错误和拼写错误。

    介绍向量空间搜索的文章通常都从介绍向量空间并说明如何将指定查询投射到项空间 (term space) 中开始。让我们通过以下示例来逆向工作:假设指定查询 Nathen,我们需要按照该顺序匹配 NathanJonathan 的数据项。现有方法可能涉及根据词的词干或变音位构建正则表达式,以及其他搜索词的语言派生词。在我们的例子中,可以通过为词中的每个字母创建向量并返回向量空间中最接近的匹配结果来获得有效的搜索结果。在本例中,首先将打印 Nathan 结果,因为它的六个字母(向量)中有五个共有字母,而其次将打印 Jonathan,因为它的八个字母中只有五个共有字母。

    本 文中的代码和描述高度简化地演示了向量空间及高效搜索向量空间的方法。幸运的是,我们有 Maciej Ceglowski 编写的优秀 Search::VectorSpace 模块来封装逻辑、算法和负载,便于高效地使用向量空间。要了解向量空间的理论和实践所需的所有信息和代码,请参阅 参考资料

    向量空间搜索方法通常适用于自由形式 (free-form) 的文本,包括帮助在向量空间中将一段文本与其他文本区分开来的某些词。Web 页面、科学研究报告和其他形式的自然语言作品最适于使用向量空间搜索方法。

    LDAP 数据通常包含一组高度冗余的组件和一组惟一数据组件。姓氏(例如 harrington 与 herrington)、电话号码和其他字段的惟一性可能导致得到含糊的搜索结果,因为查询与数据集之间共有的向量数非常少。传统的向量空间方法将把诸如 harrington 之类的词作为一个向量来处理。但是,本文中使用的方法将把词中的每个字母作为一个向量来处理。能够忽略拼写错误(搜索名称时常会遇到此类问题)、不受印刷 错误的影响(例如 919-415-2042)、把每个字母数字字符分离为词变形是一种在向量空间搜索引擎中使用 LDAP 数据的快速而轻松的管理方法。

    本文转自:IBM developerWorks 中国

    请点击此处查看全文http://ibm.csdn.net/ISN_J.aspx?action=JMP&pointid=2499

     

     
    展开全文
  • 基于LDAP的用户管理数据结构

    千次阅读 2017-02-27 17:04:29
    20160517用户管理数据结构定义(用户-角色-权限) 1.Structure  dc=uniswdc,dc=com  |  
  • LDAP结构

    千次阅读 2007-03-27 09:53:00
    LDAP结构 翻译人:林勇 QQ:313340285Email:showsscel@gmail.com MSN:showsscel@hotmail.comSkype:showsscel LDAP结构LDAP Structures 2007年3月16日版本:1.0 
  • 它即不是目录也不是数据库,LDAP是一个在目录环境中客户端如何能够访问和更新数据的访问协议。些刻,shark的用户组和认证API接口的LDAP实现支持LDAP结构的两种类型。第一种结构是标记类型0,第二种结构是标记类型1。...
  • 页面需要展示通讯录信息,数据是存储在LDAP服务器中,使用...LDAP中的数据如下图,树形结构是根据distinguishedName的值来分级的。 如其中的一个记录的distinguishedName为: CN=丁XX,OU=市场部,OU=XX科技,OU=XX...
  • java实现LDAP数据的增删改查

    千次阅读 2018-04-04 15:33:29
    本文java代码实现LDAP数据的增删改查;ldap在很多系统中被使用,再具体的业务中需要写代码来实现ldap的数据管理。
  • LDAP

    2019-06-28 16:28:54
    1、LDAP结构用树来表示,而不是用表格。正因为这样,就不能用SQL语句了。 2、LDAP可以很快地得到查询结果,不过在写方面,就慢得多。 3、LDAP提供了静态数据的快速查询方式。 4、Client/server模型,Server 用于...
  • LDAP查询数据(JAVA)

    千次阅读 2020-08-30 10:57:05
    公司让从ldap中查询对应得数据,去验证用户得信息,以前没接触过ldap,找了找网上其他人写得也不太全,经过几天得研究整理最后完成了,特写下这个方便自己以后来看 提示:以下是本篇文章正文内容,下面案例可供参考 ...
  • LDAP目录的结构

    千次阅读 2013-12-12 14:54:15
    LDAP目录以树状的层次结构来组织和存储数据,目录由目录入口对象 (Entry)组成,目录入口对象(Entry)相当于关系数据库中表的记录,可直接成为 LDAP目录记录,是具有区别名DN(Distinguished Name)的属性(Attribute...
  • LDAP基础知识

    2011-08-21 17:03:35
    LDAP基础知识 1. LDAP介绍 2. LDAP数据结构 3. LDAP数据推送 4. Windows域环境中的LDAP 5. 使用域环境中的LDAP认证WEB应用 6. 参考资料 ...
  • ldap

    2019-09-29 20:41:28
    LDAP结构 LDAP语法 LDAP命令 该篇慢慢补充,之后再进行拆分。 关于bwapp中的ldap 花了一个晚上的时间,下载了bwapp-box,打开。 几个困惑的点: php ldap_connect()函数 打开bwapp的ldap...
  • springboot+ldap+Jpa

    2020-01-03 11:11:25
    1、ldap数据结构图 2、springboot项目application-dev.properties配置 #AD域 spring.ldap.urls=ldap://192.168.2.133 spring.ldap.base=DC=dms,DC=yudean,DC=com spring.ldap.username=bigdata spring.ldap....
  • 数据仓库之LDAP

    2012-08-22 10:54:00
    数据仓库之LDAP 原文:http://baike.baidu.com/view/159263.htm LDAP是轻量目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,229
精华内容 8,491
热门标签
关键字:

ldap数据结构