【问题标题】:Shiro LDAP Authorization configShiro LDAP 授权配置
【发布时间】:2014-07-26 13:49:21
【问题描述】:

您能帮我解决以下情况吗?

背景信息:

[主要]

contextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory 
contextFactory.url = ldaps://<SERVER>:636 
contextFactory.systemUsername = <USERNAME>@<COMPANY>
contextFactory.systemPassword = <PASSWORD>
contextFactory.environment[java.naming.security.protocol] = ssl 

realm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm 
realm.ldapContextFactory = $contextFactory 
realm.searchBase = "OU=<APPDIR>,DC=<COMPANY>,DC=lcl" 
realm.groupRolesMap = "CN=<ROLE>,OU=<APPDIR>,DC=<COMPANY>,DC=lcl":"Admin"

[角色]

 # 'Admin' role has permissions * 
 Admin = * 

目标

  • 基于 currentUser 的 memberOf 字段的授权映射。

问题

  • currentUser.hasRole("Admin") 总是返回 false。

问题

  • 上面的 shiro.ini 是否正确?
  • 我该如何解决这个问题?

【问题讨论】:

    标签: java authentication ldap vaadin shiro


    【解决方案1】:

    我在使用 Shiro 1.2.4 时遇到了类似的问题。您的 Shiro 配置可能没问题,问题在于 ActiveDirectory 配置。

    在我的设置中,一些用户设置了 userPrincipalName 属性,而其他用户则没有。例如,您可以使用Sysinternals Active Directory Explorer 检查您的 AD 服务器。
    此属性是 Shiro 用于搜索特定用户的属性,然后它会查找在 memberOf 属性中定义的组。
    看看ActiveDirectoryRealm.java源码,方法Set&lt;String&gt; getRoleNamesForUser(String username, LdapContext ldapContext)使用的具体查询是
    String searchFilter = "(&amp;(objectClass=*)(userPrincipalName={0}))";

    所以你有两个解决方案:

    • 为每个用户设置 userPrincipalName 属性
    • 更改 Shiro 搜索用户的方式

    我选择了第二种解决方案。更改搜索查询比应有的更难:您必须自定义 ActiveDirectoryRealm 类的 queryForAuthorizationInfo 和 getRoleNamesForUser(因为它是私有的)方法。我就是这样做的:

    public class CustomActiveDirectoryRealm extends ActiveDirectoryRealm {
    
        @Override
        protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
            String username = (String) getAvailablePrincipal(principals);
    
            // Perform context search
            LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
    
            Set<String> roleNames = null;
    
            try {
                roleNames = getRoleNamesForUser(username, ldapContext);
    
            } finally {
                LdapUtils.closeContext(ldapContext);
            }
    
            return buildAuthorizationInfo(roleNames);
        }
    
        // Customize your search query here
        private static final String USER_SEARCH_FILTER = "(&(objectClass=*)(sn={0}))";
        private Set<String> getRoleNamesForUser(String username, LdapContext ldapContext) throws NamingException {
            Set<String> roleNames;
            roleNames = new LinkedHashSet<String>();
    
            SearchControls searchCtls = new SearchControls();
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
            String userPrincipalName = username.replace("acegas\\", "");
            if (principalSuffix != null) {
                userPrincipalName += principalSuffix;
            }
    
            Object[] searchArguments = new Object[]{userPrincipalName};
    
            NamingEnumeration answer = ldapContext.search(searchBase, USER_SEARCH_FILTER, searchArguments, searchCtls);
    
            while (answer.hasMoreElements()) {
                SearchResult sr = (SearchResult) answer.next();
    
                Attributes attrs = sr.getAttributes();
    
                if (attrs != null) {
                    NamingEnumeration ae = attrs.getAll();
                    while (ae.hasMore()) {
                        Attribute attr = (Attribute) ae.next();
    
                        if (attr.getID().equals("memberOf")) {
    
                            Collection<String> groupNames = LdapUtils.getAllAttributeValues(attr);
    
                            Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames);
                            roleNames.addAll(rolesForGroups);
                        }
                    }
                }
            }
            return roleNames;
        }
    }
    

    然后当然在 shiro.ini 中使用这个类作为 Realm

    [main]
    realm = your.package.CustomActiveDirectoryRealm
    realm.ldapContextFactory = $contextFactory 
    realm.searchBase = "OU=<APPDIR>,DC=<COMPANY>,DC=lcl" 
    realm.groupRolesMap = "CN=<ROLE>,OU=<APPDIR>,DC=<COMPANY>,DC=lcl":"Admin"
    

    【讨论】:

      猜你喜欢
      • 2012-08-23
      • 2018-07-31
      • 2013-10-28
      • 2015-09-09
      • 2015-12-24
      • 2017-02-01
      • 2016-09-28
      • 2011-09-08
      • 2019-04-20
      相关资源
      最近更新 更多