[zeppelin] 支持多组LdapRealm登录

需求:

zeppelin(v:0.8.0) 目前接入了单个邮箱的Ldap验证,公司资源整合之后,需要支持多个邮箱Ldap验证,经研究发现,zeppelin使用的是shiro进行权限验证,shiro配置是支持多组Realm验证,配置上筛选器就可以。

shiro 多Realm

配置解析

zeppelindir/conf/shiro.ini 为zepplin中shiro 配置路径

  • 简单示例:
用户
[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
zhang=123,role1,role2
wang=123,role2 
#权限
[roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#角色role3对资源user拥有create权限
role3=user:create
  • ini配置中主要配置有四大类:main,users,roles,urls
[main]
#提供了对根对象 securityManager 及其依赖的配置
securityManager=org.apache.shiro.mgt.DefaultSecurityManager
…………
securityManager.realms=$jdbcRealm
 
[users]
#提供了对用户/密码及其角色的配置,用户名=密码,角色 1,角色 2
username=password,role1,role2
 
 
[roles]
#提供了角色及权限之间关系的配置,角色=权限 1,权限 2
role1=permission1,permission2
 
 
[urls]
#用于 web,提供了对 web url 拦截相关的配置,url=拦截器[参数],拦截器
/index.html = anon
/admin/** = authc, roles[admin], perms["permission1"]

main主要配置shiro的一些对象,例如securityManager ,Realm,authenticator,authcStrategy 等等,例如

[main]
#声明一个realm  
MyRealm1=com.shiro.mutilrealm.MyRealm1
MyRealm2=com.shiro.mutilrealm.MyRealm2
 
#配置验证器
authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator
 
# AllSuccessfulStrategy 表示 MyRealm1和MyRealm2 认证都通过才算通过
#配置策略
#authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy
authcStrategy = com.shiro.authenticationstrategy.MyAuthenticationStrategy
 
 
#将验证器和策略关联起来
authenticator.authenticationStrategy = $authcStrategy
 
 
#配置验证器所使用的Realm
authenticator.realms=$MyRealm2,$MyRealm1
 
#把Authenticator设置给securityManager
securityManager.authenticator = $authenticator

在这里我们就找到了想要的

配置多Ldap Realm

示例:

[main]
### @ucarinc.com Ldap Realm
ucarRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
ucarRealm.systemUsername = ucarinc\ldapZeppelin

#use either systemPassword or hadoopSecurityCredentialPath, more details in http://zeppelin.apache.org/docs/latest/security/shiroauthentication.html
ucarRealm.systemPassword = abcd.1234
ucarRealm.searchBase = OU=总部集团,OU=神州优车集团,DC=ucarinc,DC=com
ucarRealm.url = ldap://10.100.20.26:389
ucarRealm.groupRolesMap = "CN=tech_plat_zeppelin_admin,OU=group,OU=邮件组,DC=ucarinc,DC=com":"admin"

### @test1.com Ldap Realm 
zucheRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
zucheRealm.systemUsername = test1@admin.com
zucheRealm.systemPassword = test1PED
zucheRealm.searchBase = ou=Test1,dc=test1,dc=com
zucheRealm.url = ldap://test1host:test1port
zucheRealm.groupRolesMap = "CN=admin,OU=group,DC=test1,DC=com":"admin"

### @test1.com Ldap Realm 
test1Realm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
test1Realm.systemUsername = test1@admin.com
test1Realm.systemPassword = test1PED
test1Realm.searchBase = ou=Test1,dc=test1,dc=com
test1Realm.url = ldap://test1host:test1port
test1Realm.groupRolesMap = "CN=admin,OU=group,DC=test1,DC=com":"admin"

### @test2.com Ldap Realm 
test2Realm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
test2Realm.systemUsername = test2@admin.com
test2Realm.systemPassword = test2PED
test2Realm.searchBase = ou=Test2,dc=test2,dc=com
test2Realm.url = ldap://test2host:test2port
test2Realm.groupRolesMap = "CN=admin,OU=group,DC=test2,DC=com":"admin"
#配置验证器
ucarauthenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator

#配置验证器所使用的Realm
ucarauthenticator.realms=$test1Realm,$test2Realm

#配置策略
ucarauthcStrategy = org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy

#将验证器和策略关联起来
ucarauthenticator.authenticationStrategy = $ucarauthcStrategy

 
#把Authenticator设置给securityManager
securityManager.authenticator = $ucarauthenticator

bug 解决

部署zeppelin 发现,在登录时不对,有错误发生,经排查发现在SecurityUtils.getRoles();

SecurityUtils.getRoles

经查询发现,是没有捕获找不到ldaprole错误导致:
SecurityUtils

改成如下:

public static HashSet<String> getRoles() {
    if (!isEnabled) {
      return EMPTY_HASHSET;
    }
    Subject subject = org.apache.shiro.SecurityUtils.getSubject();
    HashSet<String> roles = new HashSet<>();
    Map allRoles = null;

    try {
      if (subject.isAuthenticated()) {
        Collection realmsList = SecurityUtils.getRealmsList();
        for (Iterator<Realm> iterator = realmsList.iterator(); iterator.hasNext(); ) {
          Realm realm = iterator.next();
          String name = realm.getClass().getName();
          if (name.equals("org.apache.shiro.realm.text.IniRealm")) {
            allRoles = ((IniRealm) realm).getIni().get("roles");
            break;
          } else if (name.equals("org.apache.zeppelin.realm.LdapRealm")) {
            try {
              AuthorizationInfo auth = ((LdapRealm) realm).queryForAuthorizationInfo(
                      new SimplePrincipalCollection(subject.getPrincipal(), realm.getName()),
                      ((LdapRealm) realm).getContextFactory()
              );
              if (auth != null) {
                roles = new HashSet<>(auth.getRoles());
              }
            } catch (NamingException e) {
              log.error("Can't fetch roles", e);
            }
            break;
          } else if (name.equals("org.apache.zeppelin.realm.ActiveDirectoryGroupRealm")) {
            allRoles = ((ActiveDirectoryGroupRealm) realm).getListRoles();
            break;
          }
        }
        if (allRoles != null) {
          Iterator it = allRoles.entrySet().iterator();
          while (it.hasNext()) {
            Map.Entry pair = (Map.Entry) it.next();
            if (subject.hasRole((String) pair.getKey())) {
              roles.add((String) pair.getKey());
            }
          }
        }
      }
    } catch (Exception ex){
      log.error("getRoles error: " , ex);
    }
    return roles;
  }

部署成功!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值