Azkaban的LDAP身份验证

Azkaban的LDAP身份验证,ldap,azkaban,Ldap,Azkaban,我们正在尝试在生产环境中使用LDAP身份验证设置Azkaban。关于如何做到这一点有什么线索吗?文档说,可以通过扩展UserManager类添加插件jar文件来实现。我是azkaban的新手,正在寻找一些示例代码,您需要安装一个自定义的“用户管理器”插件。可以在github上找到它: 关于如何配置user manager插件的说明可以在github repo的首页上找到 本质上,您需要: 下载并构建插件 将内置的.jar文件复制到Azkaban安装的./extlib目录中 编辑azkaban.p

我们正在尝试在生产环境中使用LDAP身份验证设置Azkaban。关于如何做到这一点有什么线索吗?文档说,可以通过扩展UserManager类添加插件jar文件来实现。我是azkaban的新手,正在寻找一些示例代码,您需要安装一个自定义的“用户管理器”插件。可以在github上找到它:

关于如何配置user manager插件的说明可以在github repo的首页上找到

本质上,您需要:

  • 下载并构建插件
  • 将内置的.jar文件复制到Azkaban安装的./extlib目录中
  • 编辑azkaban.properties文件,指定user.manager.class和许多user.manager.ldap属性
    我们还想在azkaban中设置LDAP身份验证,但是第一个答案中提到的开源项目的功能非常有限,不允许在与LDAP服务器建立连接后启动TLS协商

    我们编写了一个全新的java类来处理以下场景:

    • 不安全地建立LDAP连接(在端口389上)
    • 启动TLS响应和TLS协商
    • 然后A识别用户凭据
    使用这种方法,我们也不必仅为azkaban在LDAP中创建服务用户

    查看示例代码块

    @Override
    public User getUser(String username, String password) throws UserManagerException {
        if (username == null || username.trim().isEmpty()) {
            throw new UserManagerException("Username is empty.");
        } else if (password == null || password.trim().isEmpty()) {
            throw new UserManagerException("Password is empty.");
        }
    
        String email = null;
        String groups = null;
        StringBuilder url = new StringBuilder("ldap://").append(ldapHost).append(":").append(ldapPort);
    
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, url.toString());
    
        try {
            // Create initial context
            LdapContext ctx = new InitialLdapContext(env, null);
            // Start TLS
            StartTlsResponse tls = (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
            SSLSession sess = tls.negotiate();
    
            // Adding username and password to environment
            StringBuilder sb = new StringBuilder("uid=").append(username).append(",").append(ldapUserBase);
            ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, sb.toString());
            ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
    
            // Search the user in a LDAP directory
            final LdapCtx x = (LdapCtx) ctx.lookup(sb.toString());
    
            // Lookup is successful - creating an Azkaban user
            User user = new User(username);
    
            // Searching LDAP directory to get email and group
            SearchControls ctls = new SearchControls();
            String[] attributes = { "cn", "memberOf", "mail" };
            ctls.setReturningAttributes(attributes);
    
            NamingEnumeration<?> answer = ctx.search(ldapUserBase, "(uid=" + username + ")", ctls);
    
            Boolean isAdmin = false;
            // Search user email and groups
            while (answer.hasMore()) {
                SearchResult rslt = (SearchResult) answer.next();
                Attributes attrs = rslt.getAttributes();
                groups = attrs.get("memberof").toString().split(":")[1].trim();
                if (attrs.get("memberof") != null && attrs.get("memberof").toString().split(":").length > 0) {
                    groups = attrs.get("memberof").toString().split(":")[1].trim();
                    for (String group : groups.split(",")) {
                        if (ldapAdminGroups.contains(group))
                            isAdmin = true;
                    }
                }
                if (attrs.get("mail") != null) {
                    email = attrs.get("mail").toString().split(":")[1].trim();
                    user.setEmail(email);
                }
            }
    
            // Assign the correct role
            if (isAdmin)
                user.addRole("admin");
            else
                user.addRole("read");
            ctx.close();
            return user;
        } catch (NamingException e) {
            throw new UserManagerException("LDAP error: " + e.getMessage(), e);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw new UserManagerException("IO error", e);
        }
    }
    
    @覆盖
    公共用户getUser(字符串用户名、字符串密码)引发UserManagerException{
    if(username==null | | username.trim().isEmpty()){
    抛出新的UserManagerException(“用户名为空”);
    }else if(password==null | | password.trim().isEmpty()){
    抛出新的UserManagerException(“密码为空”);
    }
    字符串email=null;
    字符串组=null;
    StringBuilderURL=newStringBuilder(“ldap:/”).append(ldapHost.append(“:”).append(ldaport);
    Hashtable env=新的Hashtable();
    put(Context.INITIAL\u Context\u工厂,“com.sun.jndi.ldap.LdapCtxFactory”);
    put(Context.PROVIDER_URL,URL.toString());
    试一试{
    //创建初始上下文
    LdapContext ctx=新的初始LdapContext(env,null);
    //启动TLS
    StartTlsResponse tls=(StartTlsResponse)ctx.extendedOperation(新的StartTlsRequest());
    SSLSession sess=tls.negotiate();
    //向环境中添加用户名和密码
    StringBuilder sb=new StringBuilder(“uid=”).append(用户名).append(“,”).append(ldapUserBase);
    ctx.addToEnvironment(Context.SECURITY_认证,“简单”);
    ctx.addToEnvironment(Context.SECURITY_PRINCIPAL,sb.toString());
    ctx.addToEnvironment(Context.SECURITY\u凭证、密码);
    //在LDAP目录中搜索用户
    最终LdapCtx=(LdapCtx)ctx.lookup(sb.toString());
    //查找成功-创建Azkaban用户
    用户=新用户(用户名);
    //搜索LDAP目录以获取电子邮件和组
    SearchControls ctls=新的SearchControls();
    字符串[]属性={“cn”、“memberOf”、“mail”};
    设置返回属性(属性);
    NamingEnumeration answer=ctx.search(ldapUserBase,”(uid=“+username+”),ctls);
    布尔值isAdmin=false;
    //搜索用户电子邮件和组
    while(answer.hasMore()){
    SearchResult rslt=(SearchResult)answer.next();
    Attributes attrs=rslt.getAttributes();
    groups=attrs.get(“memberof”).toString().split(“:”[1].trim();
    if(attrs.get(“memberof”)!=null&&attrs.get(“memberof”).toString().split(“:”).length>0){
    groups=attrs.get(“memberof”).toString().split(“:”[1].trim();
    对于(字符串组:groups.split(“,”)){
    if(ldapAdminGroups.contains(组))
    isAdmin=true;
    }
    }
    if(attrs.get(“邮件”)!=null){
    email=attrs.get(“mail”).toString().split(“:”[1].trim();
    user.setEmail(email);
    }
    }
    //分配正确的角色
    如果(isAdmin)
    user.addRole(“admin”);
    其他的
    user.addRole(“读取”);
    ctx.close();
    返回用户;
    }捕获(NamingE例外){
    抛出新的UserManagerException(“LDAP错误:+e.getMessage(),e);
    }捕获(IOE异常){
    //TODO自动生成的捕捉块
    抛出新的UserManagerException(“IO错误”,e);
    }
    }
    
    注意:我在这方面没有做太多的异常处理-您需要根据自己的需要来做

    如何使其在阿兹卡班工作:

    • 构建一个maven或gradle项目
    • 不需要额外的库(Azkaban除外-即com.linkedin.Azkaban)
    • 拥有一个将继承“azkaban.user.UserManager”的新类
    • 在azkaban/extlibs中构建并复制jar
    • 在azkaban.properties中,设置“user.manager.class=”以及所有必需的属性,如主机、端口和ldap用户库(ou=Users,dc=stackoverflow,dc=com)详细信息
    您应该能够通过LDAP对用户进行身份验证

    快乐编码

    谢谢, 侯赛因·博拉