Как выполнить поиск полей ldap при использовании ActiveDirectoryRealm в 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

Я могу аутентифицироваться в Широ, используя следующие строки:

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?


person oli-ver    schedule 23.08.2016    source источник


Ответы (1)


Это зависит от того, что вы пытаетесь сделать. Вы просто пытаетесь повторно использовать контекст для запуска запроса для чего-то другого, кроме аутентификации или авторизации? Или вы пытаетесь изменить поведение запроса в области AD?

В последнем случае вам потребуется расширить ActiveDirectoryRealm и переопределить метод queryForAuthorizationInfo().

Вы внедряете что-то специальное для вашей среды?

(обновлено)

Пара моментов: область имеет доступ к LdapContext в двух точках взаимодействия: queryForAuthenticationInfo() и queryForAuthorizationInfo(), поэтому, если вы расширяете область AD или AbstractLdapRealm, она у вас уже должна быть. Вы можете изменить запрос, чтобы он возвращал другую информацию и добавьте дополнительную информацию к вашему Принципалу. Тогда у вас есть доступ к этой информации непосредственно из вашего объекта Subject.

Ваши сферы не обязательно должны быть одиночными.

Если вы хотите выполнить какое-либо другое управление пользователями (отправить электронное письмо всем пользователям с заданной ролью, создать пользователя и т. д.). Затем вы можете создать LdapContextFactory в своем shiro.ini и использовать один и тот же экземпляр для нескольких объектов.

[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.

person Brian Demers    schedule 23.08.2016
comment
ну, это могло бы помочь, возможно. Но даже если я расширяю ActiveDirectoryRealm: как я могу получить экземпляр, созданный при чтении из shiro.ini? Одним из возможных решений было бы создание нового класса, расширяющего ActiveDirectoryRealm как Singleton. У вас есть другая идея? И да: я хочу повторно использовать уже существующий контекст для запроса i. е. имя и адрес электронной почты пользователя. - person oli-ver; 24.08.2016
comment
Большое спасибо! Расширение AD Realm помогло. Я думал, что должна быть возможность каким-то образом получить экземпляры, созданные при разборе файла ini, но я не смог найти такой возможности. Теперь я решил это, используя одноэлементный подход: когда вызывается конструктор моего ADRealm, я сохраняю экземпляр в статическом поле. Теперь класс использует существующий контекст ldap для получения дополнительной информации от AD. - person oli-ver; 25.08.2016