JavaDoc for Shiro class JndiLdapRealm明确表示默认情况下禁用授权,并且对LDAP服务器的授权应由用户通过继承和覆盖 JndiLdapRealm#doGetAuthorizationInfo 方法来实现。
是否存在有关如何执行此操作的示例代码,包括处理与LDAP服务器在任何地方可用的通信/协议(protocol)?

最佳答案

您应该实现自己的LdapRealm扩展JndiLdapRealm。
在此实现中,您将重写queryForAuthorizationInfo();这是一个简单的例子:

protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {

String username = (String) getAvailablePrincipal(principals);

// Perform context search
LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();

Set<String> roleNames;

try {
  roleNames = getRoleNamesForUser(username, ldapContext);
} finally {
  LdapUtils.closeContext(ldapContext);
}

return buildAuthorizationInfo(roleNames);
}

protected AuthorizationInfo buildAuthorizationInfo(Set<String> roleNames) {
return new SimpleAuthorizationInfo(roleNames);
}

protected 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);

//SHIRO-115 - prevent potential code injection:
String searchFilter = "(&(objectClass=*)(CN={0}))";
Object[] searchArguments = new Object[]{ username };

NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchArguments, searchCtls);

while (answer.hasMoreElements()) {
  SearchResult sr = (SearchResult) answer.next();

  if (log.isDebugEnabled()) {
    log.debug("Retrieving group names for user [" + sr.getName() + "]");
  }

  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);

        if (log.isDebugEnabled()) {
          log.debug("Groups found for user [" + username + "]: " + groupNames);
        }

        Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames);
        roleNames.addAll(rolesForGroups);
      }
    }
  }
}

10-07 13:48