java同步ad域账号

挑水做饭 2020年07月19日 20次浏览

公司使用ldap做统一登录,做项目时需要同步ad域账号信息到数据库,写程序拉去的时候遇到一个问题,拿不到全量账号,经各种资料查询后得知ldap服务器会做限制一次最多只能拉去1000条,其他的只能通过分页去拉取,java 分页拉取ad域账号代码的资料很少,现将项目中调试好的代码分享如下(账号需要有访问ldap目录权限):

  public static List<MgaAdUserDo> getPersonInfo() {
        log.info("进来了");
        Properties env = new Properties();

        List<MgaAdUserDo> list = new ArrayList<>();

        String adminName = "*******"; //账号
        String adminPassword = "*********"; //密码

        String ldapURL = "ldap://172.*.*.130:389";//ip:port
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");//"none","simple","strong"
        env.put(Context.SECURITY_PRINCIPAL, adminName + "@mgtv.com");
        env.put(Context.SECURITY_CREDENTIALS, adminPassword);
        env.put(Context.PROVIDER_URL, ldapURL);
        try {
            LdapContext ctx = new InitialLdapContext(env, null);
            int pageSize = 100;
            byte[] cookie = null;
            //Request the paged results control
            Control[] ctls = new Control[]{new PagedResultsControl(pageSize, true)};
            ctx.setRequestControls(ctls);
            //initialize counter to total the results

            do {
                SearchControls searchCtls = new SearchControls();
                searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                String searchFilter = "(&(objectCategory=person)(objectClass=user)(name=*))";
                String searchBase = "OU=**,OU=**,OU=Users,OU=Mgtv,DC=mgtv,DC=com";
                String returnedAtts[] = {"sn", "givenName", "description", "physicalDeliveryOfficeName", "initials", "otherTelephone",
                        "userPrincipalName", "displayName", "telephoneNumber", "mail", "mobile", "otherMobile", "company", "department", "title", "manager", "directReports"};
                searchCtls.setReturningAttributes(returnedAtts);
                NamingEnumeration<SearchResult> answer = ctx.search(searchBase, searchFilter, searchCtls);
                int totalResults = 0;
                while (answer.hasMoreElements()) {
                    totalResults++;
                    SearchResult sr = (SearchResult) answer.next();
                    log.info("<<<::[" + sr.getName() + "]::>>>>");
                    MgaAdUserDo adUserDo = new MgaAdUserDo();
                    NamingEnumeration<? extends Attribute> attrs = sr.getAttributes().getAll();
                    while (attrs.hasMore()) {
                        Attribute attr = attrs.next();
                        switch (attr.getID()) {
                            case "mail":
                                adUserDo.setMail(attr.get().toString());
                                break;
                            case "mobile":
                                adUserDo.setMobile(attr.get().toString());
                                break;
                            case "department":
                                adUserDo.setDepartment(attr.get().toString());
                                break;
                            case "displayName":
                                adUserDo.setDisplayName(attr.get().toString());
                                break;
                            case "givenName":
                                adUserDo.setGivenname(attr.get().toString());
                                break;
                            case "userPrincipalName":
                                adUserDo.setUserPrincipalName(attr.get().toString());
                                adUserDo.setAdCount(adUserDo.getUserPrincipalName().replace("@mgtv.com", ""));
                                break;
                        }

                        list.add(adUserDo);
                    }

                }

                log.info("do流程{}", totalResults);
                // examine the response controls
                cookie = parseControls(ctx.getResponseControls());
                // pass the cookie back to the server for the next page
                ctx.setRequestControls(new Control[]{new
                        PagedResultsControl(pageSize
                        , cookie, Control.CRITICAL)});

            } while ((cookie != null) && (cookie.length != 0));


            ctx.close();
        } catch (Exception e) {
            log.error("ldap出错了", e);
        }

        return list;
    }

    public static byte[] parseControls(Control[] controls) throws NamingException {
        byte[] cookie = null;
        if (controls != null) {
            for (int i = 0; i < controls.length; i++) {
                if (controls[i] instanceof PagedResultsResponseControl) {
                    PagedResultsResponseControl prrc =
                            (PagedResultsResponseControl) controls[i];
                    cookie = prrc.getCookie();
                    System.out.println(">>Next Page \n");
                }
            }
        }
        return (cookie == null) ? new byte[0] : cookie;
    }

MgaAdUserDo:

package com.mgtv.media.authority.pojo.model;

import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.Date;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * ad账号同步表
 * </p>
 *
 * @author zhongqu@mgtv.com
 * @since 2020-07-16
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("mga_ad_user")
public class MgaAdUserDo implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 统一账号
     */
    private String adCount;

    /**
     * 邮箱
     */
    private String mail;

    /**
     * 手机号
     */
    private String mobile;

    /**
     * 部门
     */
    private String department;

    /**
     * 显示名称
     */
    private String displayName;

    /**
     * givenname
     */
    private String givenname;

    /**
     * 用户统一登录域
     */
    private String userPrincipalName;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 创建时间
     */
    private Date createTime;


}