Java对接OpenLdap实现数据单向同步到MySql

Java对接OpenLdap实现数据单向同步到MySql

把配置信息写成配置项,优化代码:

最近公司项目需求有对接OpenLdap并连接MySql进行数据单向同步功能,公司里也是第一次对接,把任务交给了我,让我自行学习,并实现此功能。
在网上查阅许久,发现百分之80的博客皆是8年甚至更久远的文章,帮助并不大,Java对接OpenLdap实现数据单向同步到MySql的更是没有,所以我为了方便以后自己查阅,增强记忆,将代码以及方法贴出来。也希望能对大家有所帮助。

package com.tiduyun.cmp.biz.model.vo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import lombok.Data;
import lombok.ToString;

@Component
@Configuration
@ToString
@Data
/**
* @author huyuan@tiduyun.com
* OpenLdap服务连接信息
*/
public class OpenLdapConnectionVo {
    @Value("${cmp.biz.ldap.host}")
    private String ldapHots;
    @Value("${cmp.biz.ldap.port}")
    private String ldapPort;
    @Value("${cmp.biz.ldap.bindDn}")
    private String ldapBindDN;
    @Value("${cmp.biz.ldap.password}")
    private String ldapPassword;
    @Value("${cmp.biz.ldap.baseDn}")
    private String ldapBaseDN;
    @Value("${cmp.biz.ldap.userDefaultPassword}")
    private String userDefaultPassword;
    @Value("${cmp.biz.ldap.tenantType}")
    private Integer tenantType;

}

注:此代码适用于微服务,分布式架构,利于后期数据的更改以及维护的便利。单体架构可直接写入配置文件,在实现类中调用即可。

对应的配置文件:


注:userDefaultPassword , tenantType 这两个字段可忽略。如果不知道如何启动OpenLdap服务的小伙伴,可以到这个链接里学习一下,也是我查阅许多资料里,效果最好的一个博客,点击前往

接下来回归正题,先说明一下每个字段的意思:
host:连接的IP(也是Java连接OpenLdap最重要的)
bindDn: 即OpenLdap配置文件里的自己配置的账号。
password: 见名知意
baseDn: 即OpenLdap配置文件里自己配置的名字(此处可以理解为MySql中数据库名字)
port: OpenLdap的端口(OpenLdap默认端口389)

导入依赖

<!-- https://mvnrepository.com/artifact/com.novell.ldap/jldap -->
       <dependency>
            <groupId>com.novell.ldap</groupId>
            <artifactId>jldap</artifactId>
            <version>4.3</version>
       </dependency>

Spring也有Ldap,看个人喜好使用,我也把它贴上

        <dependency>
            <groupId>org.springframework.ldap</groupId>
            <artifactId>spring-ldap-core</artifactId>
            <version>2.3.2.RELEASE</version>
        </dependency>

Service

package com.tiduyun.cmp.biz.service;

/**
* @author huyuan@tiduyun.com
* ldapDataSynchronization LDAP数据同步
*/
public interface OpenLdapService {

    void ldapDataSynchronization();

}

实现类(连接OpenLdap代码如下)

package com.tiduyun.cmp.biz.service.impl;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import com.tiduyun.cmp.biz.constant.ApplicationContextConstants;
import com.tiduyun.cmp.common.core.constant.IsDeleted;
import com.tiduyun.cmp.user.constant.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.novell.ldap.*;
import com.tiduyun.cmp.biz.model.vo.OpenLdapConnectionVo;
import com.tiduyun.cmp.biz.service.OpenLdapService;
import com.tiduyun.cmp.biz.service.TenantService;
import com.tiduyun.cmp.biz.service.UserAccountService;
import com.tiduyun.cmp.biz.service.UserService;
import com.tiduyun.cmp.common.core.constant.BuiltInUserId;
import com.tiduyun.cmp.common.model.user.Tenant;
import com.tiduyun.cmp.common.model.user.TenantOpenLdapLinkedData;
import com.tiduyun.cmp.common.model.user.User;
import com.tiduyun.cmp.common.model.user.UserAccount;
import com.tiduyun.cmp.user.client.OpenLdapManageClient;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class OpenLdapServiceImpl implements OpenLdapService {

    @Resource
    private OpenLdapConnectionVo openLdapConnectionVo;
    
    @Override
    public void ldapDataSynchronization() {
        String searchFilter = "objectClass=*";
        int ldapPort = LDAPConnection.DEFAULT_PORT;
        int searchScope = LDAPConnection.SCOPE_SUB;
        //查询Ldap数据存入数据库
        LDAPConnection lc = new LDAPConnection();
        try {

            lc.connect(openLdapConnectionVo.getLdapHots(), ldapPort);
            lc.bind(LDAPConnection.LDAP_V3, openLdapConnectionVo.getLdapBindDN(),
                    openLdapConnectionVo.getLdapPassword().getBytes("UTF8"));
            LDAPSearchResults searchResults = lc.search(openLdapConnectionVo.getLdapBaseDN(), searchScope, searchFilter, null,
                    false);
            while (searchResults.hasMore()) {
                LDAPEntry nextEntry = null;
                try {
                    nextEntry = searchResults.next();
                } catch (LDAPException e) {
                    log.error("LDAP服务器连接失败 : " , e);
                    if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR) {
                        break;
                    } else {
                        continue;
                    }
                }
             }

Java连接OpenLdap将其数据同步至MySql,实现类完整代码如下(上条代码为连接代码)

package com.tiduyun.cmp.biz.service.impl;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import com.tiduyun.cmp.biz.constant.ApplicationContextConstants;
import com.tiduyun.cmp.common.core.constant.IsDeleted;
import com.tiduyun.cmp.user.constant.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.novell.ldap.*;
import com.tiduyun.cmp.biz.model.vo.OpenLdapConnectionVo;
import com.tiduyun.cmp.biz.service.OpenLdapService;
import com.tiduyun.cmp.biz.service.TenantService;
import com.tiduyun.cmp.biz.service.UserAccountService;
import com.tiduyun.cmp.biz.service.UserService;
import com.tiduyun.cmp.common.core.constant.BuiltInUserId;
import com.tiduyun.cmp.common.model.user.Tenant;
import com.tiduyun.cmp.common.model.user.TenantOpenLdapLinkedData;
import com.tiduyun.cmp.common.model.user.User;
import com.tiduyun.cmp.common.model.user.UserAccount;
import com.tiduyun.cmp.user.client.OpenLdapManageClient;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class OpenLdapServiceImpl implements OpenLdapService {
    //租户常量
    private final static byte isDel = IsDeleted.NO;
    private final static String tenantStatus = TenantStatus.AVAILABLE;
    //用户常量
    private final static int userType = UserType.TENANT_USER;
    private final static int userStatus = UserStatus.NORMAL;
    private final static int accountStatus = UserAccountStatus.NORMAL;
    private final static int accountType = UserAccountType.ADMIN_USER_NORMAL;
    @Resource
    private OpenLdapConnectionVo openLdapConnectionVo;
    @Autowired
    private UserService userService;
    @Autowired
    private TenantService tenantService;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private OpenLdapManageClient openLdapManageClient;

    private User systemOperatorUser;

    @PostConstruct
    public void initService() {
        systemOperatorUser = new User();
        systemOperatorUser.setId(BuiltInUserId.SYSTEM_OPERATOR_USER_ID);
        systemOperatorUser.setType(UserType.ADMIN_USER);
        systemOperatorUser.setTenantId(ApplicationContextConstants.ADMIN_USER_TENANT_ID);
        systemOperatorUser.setTopTenantId(ApplicationContextConstants.ADMIN_USER_TENANT_ID);
    }
    @Override
    public void ldapDataSynchronization() {
        String searchFilter = "objectClass=*";
        int ldapPort = LDAPConnection.DEFAULT_PORT;
        int searchScope = LDAPConnection.SCOPE_SUB;
        //查询Ldap数据存入数据库
        LDAPConnection lc = new LDAPConnection();
        try {

            lc.connect(openLdapConnectionVo.getLdapHots(), ldapPort);
            lc.bind(LDAPConnection.LDAP_V3, openLdapConnectionVo.getLdapBindDN(),
                    openLdapConnectionVo.getLdapPassword().getBytes("UTF8"));
            LDAPSearchResults searchResults = lc.search(openLdapConnectionVo.getLdapBaseDN(), searchScope, searchFilter, null,
                    false);
            while (searchResults.hasMore()) {
                LDAPEntry nextEntry = null;
                try {
                    nextEntry = searchResults.next();
                } catch (LDAPException e) {
                    log.error("LDAP服务器连接失败 : " , e);
                    if (e.getResultCode() == LDAPException.LDAP_TIMEOUT || e.getResultCode() == LDAPException.CONNECT_ERROR) {
                        break;
                    } else {
                        continue;
                    }
                }

                String ldapId = nextEntry.getDN();
                String string = ldapId.replaceAll("=", "':'").replaceAll(",", "','");
                String s = "{'"+string+"'}";

                JSONObject jsonObject= JSON.parseObject(s);
                String uid = (String)jsonObject.get("uid");
                if(StringUtils.isEmpty(uid)){
                    continue;
                }
                String ldapType = (String)jsonObject.get("ou");
                TenantOpenLdapLinkedData ldapData=new TenantOpenLdapLinkedData();
                ldapData.setLdapId(ldapId);
                ldapData.setLdapType(uid);
                ldapData.setTargetType(ldapType);
                ldapData.setCreationTime(new Date());
                ldapData.setUpdateTime(new Date());
                LDAPAttributeSet attributeSet = nextEntry.getAttributeSet();

                Object cn = attributeSet.getAttribute("cn");
                ldapData.setTargetName(getLdapDataByKey(cn));
                Object sn = attributeSet.getAttribute("sn");
                Integer snInt = Integer.parseInt(getLdapDataByKey(sn));
                TenantOpenLdapLinkedData LinkedData = openLdapManageClient.getLdapData(snInt);

                Object ObejectO =  attributeSet.getAttribute("o");
                String o = getLdapDataByKey(ObejectO);
                if(null ==LinkedData){
                    ldapData.setTargetId(snInt);
                    ldapData.setTenantId(Integer.parseInt(o));
                    openLdapManageClient.insertSelective(ldapData);
                }
            }
        } catch (LDAPException e) {
            log.error("Ldap error data : " , e);
        } catch (UnsupportedEncodingException e) {
            log.error("error message : " , e);
        } finally {
            try {
                if (lc.isConnected()) {
                    lc.disconnect();
                }
            } catch (Exception e) {
                log.error("parse error data : " , e);
            }
        }
        //Ldap租户数据同步
        List<TenantOpenLdapLinkedData> tenantList = openLdapManageClient.selectLdapByType("Tenant");
        for(TenantOpenLdapLinkedData ldapTenant:tenantList){
            String targetName = ldapTenant.getTargetName();
            Tenant tenant = openLdapManageClient.getTenantByTenantName(targetName);
            if(null==tenant){
                Tenant t=new Tenant();
                String ldapTargetName = ldapTenant.getTargetName();
                t.setName(ldapTargetName);
                t.setStatus(tenantStatus);
                t.setCreatorUserId(systemOperatorUser.getId());
                t.setType(openLdapConnectionVo.getTenantType());
                Tenant tenant1 = tenantService.addTenant(systemOperatorUser,t);
                Integer id = tenant1.getId();
                t.setId(id);
                t.setTopTenantId(id);
                openLdapManageClient.updateByPrimaryKeySelective(t);
            }
        }
        //LDAP用户数据同步
        List<TenantOpenLdapLinkedData> userList = openLdapManageClient.selectLdapByType("User");
        for(TenantOpenLdapLinkedData userTenant:userList){
            String name = userTenant.getTargetName();
            User user = openLdapManageClient.getUserByTargetName(name);
            if(null==user){
                User u=new User();
                Date date = new Date();
                String userTargetName = userTenant.getTargetName();
                Integer targetId = userTenant.getTargetId();
                //通过这个id去查询tenant的主键
                String targetNameById = openLdapManageClient.getTargetNameById(targetId);
                String idByName = openLdapManageClient.getIdByName(targetNameById);
                if(StringUtils.isEmpty(idByName)){
                    idByName="0";
                }
                int id=Integer.parseInt(idByName);
                u.setName(userTargetName);
                //LDAP数据同步用户默认值的设置
                u.setStatus(userStatus);
                u.setType(userType);
                u.setTopTenantId(id);
                u.setTenantId(id);
                u.setName(userTenant.getTargetName());
                u.setIsDeleted(isDel);
                u.setCreationTime(date);
                User user1 = userService.addTenantUser(u);

                //user_account表数据默认值
                UserAccount userAccount=new UserAccount();
                userAccount.setStatus(accountStatus);
                userAccount.setType(accountType);
                userAccount.setIsDeleted(isDel);
                userAccount.setPassword(openLdapConnectionVo.getUserDefaultPassword());
                userAccount.setCreationTime(date);
                //user_account数据
                userAccount.setUserId(user1.getId());
                userAccount.setName(userTenant.getTargetName());
                userAccountService.addUserAccount(userAccount);
            }
        }
    }

    public String getLdapDataByKey(Object o){
        String snString = o.toString();
        String pathone= snString.substring(snString.indexOf("value"));
        String snStringone = pathone.replaceAll("=", "':");
        JSONObject snJson = JSON.parseObject("{'" + snStringone);
        return snJson.get("value").toString();
    }
}

此方法为四张表关联,主要提供思路。其中的实体类,工具类等等我就不贴出来了,小伙伴们自行更改。如只需要连接OpenLdap,可以直接使用连接OpenLdap的代码,再加上你自己的方法即可。如需要连接数据库进行操作,可参考完整代码,进行更改。

以上就是Java连接OpenLdap同步其数据到MySql的方法,有许多不足欢迎指出更正,希望能对大家有帮助。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值