2016-08-23 7 views
1

Мы используем Apache Shiro для аутентификации и авторизации пользователей с использованием нашего активного каталога.Как я могу искать поля ldap при использовании ActiveDirectoryRealm в 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?

ответ

1

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

Если последнее, вам необходимо расширить ActiveDirectoryRealm и переопределить метод queryForAuthorizationInfo().

Вы внедряете что-то, что является обычным для вашей среды?

(обновлено)

Пара вещей: Сфера имеет доступ к LdapContext в двух точках соприкосновения: queryForAuthenticationInfo() и queryForAuthorizationInfo(), так что если вы расширить сферу AD или AbstractLdapRealm вы должны уже есть. Вы можете изменить запрос для возврата другой информации и add the extra info to your Principal. Затем у вас есть доступ к этой информации непосредственно из вашего объекта 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.

+0

хорошо, это может помочь. Но даже если я расширяю ActiveDirectoryRealm: как я могу получить экземпляр, созданный при чтении с shiro.ini? Одним из возможных решений было бы создание нового класса, расширяющего ActiveDirectoryRealm как Singleton. У вас есть другая идея? И да: я хочу повторно использовать существующий контекст для запроса i. е. имя и адрес электронной почты пользователя. –

+0

Большое спасибо! Расширение AD Realm сделало трюк.Я думал, что должна быть возможность получить экземпляры, созданные при разборе файла ini, но я не мог найти возможности. Теперь я решил это с использованием одноэлементного подхода: когда вызывается конструктор моего ADRealm, я сохраняю экземпляр в статическом поле. Класс теперь использует существующий контекст ldap, чтобы получить дополнительную информацию от AD. –