在 Apache Shiro 中使用 ActiveDirectoryRealm 时如何搜索 ldap 字段?

How can I search for ldap fields when using ActiveDirectoryRealm in Apache Shiro?

我们使用 Apache Shiro 对使用我们活动目录的用户进行身份验证和授权。

使用以下配置对用户和映射组进行身份验证工作得很好:

adRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
adRealm.searchBase = "OU=MYORGANIZATION,DC=MYDOMAIN,DC=COM"
adRealm.groupRolesMap = "CN=SOMEREADGROUP":"read","CN=SOMEMODIFYGROUP":"modify","CN=SOMEADMINGROUP":"admin"
adRealm.url = ldaps://my.ad.url:636
adRealm.systemUsername= systemuser
adRealm.systemPassword= secret
adRealm.principalSuffix= @myorganization.mydomain.com

我可以使用以下行在 Shiro 中进行身份验证:

String user = "someuser";
String password = "somepassword";
Subject currentUser = SecurityUtils.getSubject ();
if (!currentUser.isAuthenticated ()){
  UsernamePasswordToken token = new UsernamePasswordToken (user,
              password);
  token.setRememberMe (true);
  currentUser.login (token);
}

我们现在想从我们的 ActiveDirectory 中获取更多的用户信息。我如何使用 Apache Shiro 做到这一点?我在文档中找不到任何相关信息。

在 ActiveDirectoryRealm 的源代码中我找到了这一行:

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

所以答案的第一部分很清楚:使用 ldapContext 在其中搜索内容。但是我怎样才能检索到 LdapContext?

这取决于您要做什么。您是否只是想将上下文重新用于 运行 查询,而不是身份验证或授权?或者您是否正在尝试更改 AD 领域中的查询行为?

如果是后者,您需要扩展 ActiveDirectoryRealm 并覆盖 queryForAuthorizationInfo() 方法。

您是否正在实施为您的环境定制的东西?

(更新)

几件事: 领域可以访问两个接触点中的 LdapContext:queryForAuthenticationInfo()queryForAuthorizationInfo(),因此如果您扩展 AD 领域或 AbstractLdapRealm 您应该已经拥有它。您可以将查询更改为 return 其他信息和 add the extra info to your Principal。然后您可以直接从您的 Subject 对象访问该信息。

您的领域不需要是单例。

如果您想进行某种其他类型的用户管理(向具有给定角色的所有用户发送电子邮件、创建用户等)。然后,您可以在 shiro.ini 中创建一个 LdapContextFactory,并为多个对象使用相同的实例。

[main]
...
ldapContextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory
ldapContextFactory.systemUsername = foobar
ldapContextFactory.systemPassword = barfoo

adRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
adRealm.ldapContextFactory = $ldapContextFactory
...

myObject = com.biz.myco.MyObject
myObject.ldapContextFactory = $ldapContextFactory

如果 myObject 与其他 Shiro 组件交互(响应事件等),这会很好地工作,但如果您需要从另一个框架访问它,则效果不佳。您可以通过构建创建 ldapContextFactory 的某种静态初始化来解决此问题,但在我看来,这是使用 shiro.ini 的最佳位置,也是使用 Guice 或 Spring 的亮点所在。