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

Posted

技术标签:

【中文标题】在 Apache Shiro 中使用 ActiveDirectoryRealm 时如何搜索 ldap 字段?【英文标题】:How can I search for ldap fields when using ActiveDirectoryRealm in Apache Shiro? 【发布时间】:2016-12-30 11:09:55 【问题描述】:

我们使用 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?

【问题讨论】:

【参考方案1】:

这取决于你想要做什么。您是否只是想重用上下文来运行身份验证或授权以外的查询?或者您是否尝试更改 AD 领域中的查询行为?

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

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

(更新)

有几件事: 领域可以访问两个接触点中的 LdapContext:queryForAuthenticationInfo()queryForAuthorizationInfo(),因此如果您扩展 AD 领域或 AbstractLdapRealm,您应该已经拥有它。您可以更改查询以返回其他信息和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 的亮点。

【讨论】:

嗯,这可能会有所帮助。但即使我扩展了 ActiveDirectoryRealm:如何检索从 shiro.ini 读取时创建的实例?一种可能的解决方案是创建将 ActiveDirectoryRealm 扩展为 Singleton 的新类。你有别的想法吗?是的:我想重用已经存在的上下文来查询 i。 e.用户的姓名和电子邮件地址。 非常感谢!扩展 AD 领域就成功了。我认为在以某种方式解析ini文件时必须有可能获得创建的实例,但我找不到可能性。我现在使用单例方法解决了它:当调用我的 ADRealm 的构造函数时,我将实例保存在静态字段中。该类现在使用现有的 ldap 上下文从 AD 获取更多信息。

以上是关于在 Apache Shiro 中使用 ActiveDirectoryRealm 时如何搜索 ldap 字段?的主要内容,如果未能解决你的问题,请参考以下文章

具有自定义角色的 Shiro Active Directory

Apache Shiro 简介(转)

转Apache shiro集群实现 shiro入门介绍

Apache Shiro 使用手册Shiro 授权

Apache Shiro 使用手册Realm 实现

Apache Shiro 使用手册Shiro 认证