Azkaban的LDAP身份验证
我们正在尝试在生产环境中使用LDAP身份验证设置Azkaban。关于如何做到这一点有什么线索吗?文档说,可以通过扩展UserManager类添加插件jar文件来实现。我是azkaban的新手,正在寻找一些示例代码,您需要安装一个自定义的“用户管理器”插件。可以在github上找到它: 关于如何配置user manager插件的说明可以在github repo的首页上找到 本质上,您需要:Azkaban的LDAP身份验证,ldap,azkaban,Ldap,Azkaban,我们正在尝试在生产环境中使用LDAP身份验证设置Azkaban。关于如何做到这一点有什么线索吗?文档说,可以通过扩展UserManager类添加插件jar文件来实现。我是azkaban的新手,正在寻找一些示例代码,您需要安装一个自定义的“用户管理器”插件。可以在github上找到它: 关于如何配置user manager插件的说明可以在github repo的首页上找到 本质上,您需要: 下载并构建插件 将内置的.jar文件复制到Azkaban安装的./extlib目录中 编辑azkaban.p
我们还想在azkaban中设置LDAP身份验证,但是第一个答案中提到的开源项目的功能非常有限,不允许在与LDAP服务器建立连接后启动TLS协商 我们编写了一个全新的java类来处理以下场景:
- 不安全地建立LDAP连接(在端口389上)
- 启动TLS响应和TLS协商
- 然后A识别用户凭据
@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)详细信息