如何在没有系统用户的情况下在Shiro中搜索AD组?

时间:2016-09-15 18:37:28

标签: active-directory shiro

我正在使用Shiro使用ActiveDirectoryRealm对Active Directory进行身份验证。这部分工作正常,我可以登录。

但是,我无法搜索角色/群组。

我怀疑是因为我没有配置systemUsername/systemPassword。我也没有这个选择。

如果我使用像LdapAdmin这样的应用程序,我必须将我的电子邮件和密码放在身份验证字段中才能连接和浏览。

LdapAdmin Connection Properties

当我使用Spring Security时,我不必提供任何此类“systemUser”。我猜它使用了我提供的相同用户名/密码凭据来登录。

如何配置Shiro执行相同操作?

请参阅下文,了解我的shiro.ini的粗略版本。

adRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
adRealm.url = ldap://my.ad.url:389
adRealm.principalSuffix=@example.com
adRealm.systemUsername= 
adRealm.systemPassword= 
adRealm.searchBase = "OU=org,DC=example,DC=com"
adRealm.groupRolesMap = "CN=admins":"admin"

2 个答案:

答案 0 :(得分:0)

目前它不支持这一点。

当检查验证时,可以改进当前实现以查询角色信息。 (这是领域可以访问用户凭据的唯一点)

答案 1 :(得分:0)

正如评论中所建议的,我创建了一个自定义域(扩展ActiveDirectoryRealm)以在登录期间搜索角色,然后直接访问它们,而不是尝试使用系统用户进行搜索。

下面是突出的代码,完整代码在GitHub上。

  /**
   * This is called during the log in process.
   * Authenticate but also store the roles/groups on a custom principal
   */
  @Override
  protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
    SimpleAuthenticationInfo authenticationInfo = (SimpleAuthenticationInfo)super.queryForAuthenticationInfo(token, ldapContextFactory);
    PrincipalCollection principals = authenticationInfo.getPrincipals();

    UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
    String username = usernamePasswordToken.getUsername();
    String userPrincipalName = getUserPrincipalName(token);

    Set<String> roleNames;
    // Binds using the username and password provided by the user.
    LdapContext ldapContext = null;
    try {
      ldapContext = ldapContextFactory.getLdapContext(userPrincipalName, (usernamePasswordToken.getPassword()));
      roleNames = getRoleNamesForUser(username, ldapContext);
    } finally {
      LdapUtils.closeContext(ldapContext);
    }

    List<UserPrincipal> customPrincipals = getCustomPrincipals(userPrincipalName, roleNames);

    //Merge the custom principals and the main principals
    SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(customPrincipals, CustomActiveDirectoryRealm.class.getSimpleName());
    principalCollection.addAll(principals);

    authenticationInfo.setPrincipals(principalCollection);

    return authenticationInfo;
  }


  /**
   * This is called during checks for hasRole.
   * Use the roles that we found on login
   */
  @Override
  protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
    UserPrincipal availablePrincipal = (UserPrincipal)getAvailablePrincipal(principals);
    Set<String> roleNames = availablePrincipal.getRoleNames();

    return buildAuthorizationInfo(roleNames);
  }