在 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 字段?的主要内容,如果未能解决你的问题,请参考以下文章