Главная » Spring » Аутентификация с использованием LDAP Spring

0

Все мы один или два раза видели структуру какой-либо органи- зации. Большинство организаций имеют иерархическую структуру. Служащие подчинены своими руководителями, руководители – директорам, директора – президентам и т. д. В подобной иерархии всегда можно усмотреть аналогии с иерархической организацией правил безопасности. Служащим отдела кадров, вероятно, потребу- ются привилегии, дающие право вести учет персонала. Руководи- телям наверняка потребуется более широкий круг привилегий, чем их подчиненным.

Реляционные базы данных с успехом могут использоваться для хранения информации, но они плохо подходят для представления данных с иерархической организацией. С другой стороны, каталоги LDAP превосходно справляются с этим. По этой причине очень час- то для отражения структурной организации компании использует- ся каталог LDAP, и также часто ограничения системы безопасности отображаются на записи в каталоге.

Чтобы использовать механизм аутентификации на основе LDAP, сначала необходимо задействовать модуль LDAP, входящий в состав Spring Security, и настроить аутентификацию посредством LDAP в контексте приложения Spring. Что касается настройки аутенти- фикации через LDAP, имеются два варианта:

# с помощью провайдера аутентификации с поддержкой LDAP;

# с помощью службы учета пользователей с поддержкой LDAP. По большому счету, это даже не выбор. Но есть некоторые ню-

ансы, которые необходимо учитывать при выборе того или иного

механизма.

Объявление провайдера с поддержкой LDAP

Настраивая службы учета пользователей с хранилищем в памяти и на основе JDBC, мы объявляли элемент <authentication-provider> и внедряли в него службу учета пользователей. То же самое можно сделать и со службой учета пользователей на основе LDAP (и чуть ниже будет показано, как это сделать). Но более простой способ заключается в использовании специализированного провайдера аутентификации, обладающего поддержкой LDAP, для чего необ- ходимо  объявить  элемент  <ldap-authentication-provider>   в  элемент

<authentication-manager>:

<authentication-manager alias="authenticationManager">

<ldap-authentication-provider

user-search-filter="(uid={0})" group-search-filter="member={0}"/>

</authentication-manager>

Атрибуты user-search-filter и group-search-filter определяют фильтры для базовых запросов LDAP, которые используются для поиска пользователей и групп. По умолчанию базовые запросы на получение информации о пользователях и группах пусты, вслед- ствие чего поиск будет выполняться от корня иерархии LDAP. Но есть возможность изменить базовые запросы:

<ldap-user-service   id="userService" user-search-base="ou=people" user-search-filter="(uid={0})" group-search-base="ou=groups"

group-search-filter="member={0}"   />

Атрибут user-search-base определяет  базовый  запрос  для  поис- ка пользователей. Аналогично атрибут group-search-base определяет базовый запрос для поиска групп. Здесь указывается, что поиск пользователей должен выполняться не от корня иерархии, а там, где организационной единицей является человек. Аналогично по-

иск групп должен выполняться там, где организационной единицей являются группы.

Настройка сравнения паролей

По умолчанию процедура аутентификации с использованием LDAP заключается в выполнении  операции связывания,  когда аутентификация пользователя производится непосредственно на сервере LDAP. Другой вариант состоит в том, чтобы выполнить процедуру сравнения. Она заключается в отправке пароля в ката- лог LDAP и получении результатов сравнения с сервера. Поскольку сравнение выполняется сервером LDAP, секретность фактического пароля не нарушается.

Если предпочтение будет отдано аутентификации посредством сравнения паролей, реализовать ее можно, объявив элемент <password- compare>:

<ldap-authentication-provider

user-search-filter="(uid={0})" group-search-filter="member={0}">

<password-compare  />

</ldap-authentication-provider>

Согласно этому объявлению, пароль, введенный пользователем в форме аутентификации, будет сравниваться со значением атри- бута userPassword в учетной записи пользователя на сервере LDAP. Если пароль хранится в другом атрибуте, его имя можно определить в  атрибуте  password-attribute:

<password-compare hash="md5" password-attribute="passcode"  />

Это здорово, что при использовании процедуры аутентификации посредством сравнения паролей секретность фактического пароля не нарушается. Но принятый от пользователя пароль необходимо передать серверу LDAP по сети, где он может быть перехвачен зло- умышленником. Чтобы предотвратить такую возможность, можно определить стратегию шифрования трафика, присвоив атрибуту hash одно из следующих значений:

# {sha};

# {ssha};

# md4;

# md5;

#  plaintext;

# sha;

# sha-256.

В нашем примере мы будем шифровать пароли с использованием алгоритма MD5, установив значение md5 в атрибуте hash.

Обращение к удаленному серверу LDAP

Осталась еще одна нерешенная проблема – как указать фактиче- ский адрес сервера LDAP и местоположение данных. Мы успешно справились с настройкой Spring для аутентификации на сервере LDAP, но как быть с самим сервером?

По умолчанию модуль Spring Security LDAP предполагает, что сервер LDAP выполняется на локальном компьютере (localhost) и для приема запросов использует порт с номером 33389. Но если сер- вер LDAP выполняется на другом компьютере, для настройки его адреса можно воспользоваться элементом <ldap-server>:

<ldap-server url="ldap://habuma.com:389/dc=habuma,dc=com" />

Здесь адрес сервера LDAP определяется атрибутом url1.

Настройка встроенного сервера LDAP

Если так случилось, что у вас нет сервера LDAP, готового вы- полнить запросы на аутентификацию, с помощью все того же эле- мента <ldap-server> можно настроить работу со встроенным сервером LDAP. Для этого достаточно просто убрать атрибут url. Например:

<ldap-server root="dc=habuma,dc=com" />

Атрибут root указывать необязательно. Но по умолчанию он име- ет значение dc=springframework,dc=org, что, как мне кажется, не совсем то, что вам захочется использовать в качестве корня.

Когда сервер LDAP запустится, он попытается загрузить данные из файлов в формате LDIF, которые ему удастся обнаружить в биб- лиотеке классов (classpath). Формат LDIF (LDAP Data Interchange Format – формат обмена данными с сервером LDAP) – это стандарт- ный способ представления данных LDAP в виде текстовых файлов.

1   Даже не пытайтесь использовать этот URL. Это всего лишь пример. По указанному URL в действительности нет никакого сервера LDAP.

Каждая запись занимает одну или более строк и содержит пары имя:значение. Друг от друга записи отделяются пустыми строками1.

Те, кто предпочитает явно указывать, какой файл LDIF следует загрузить, могут воспользоваться атрибутом ldif:

<ldap-server   root="dc=habuma,dc=com" ldif="classpath:users.ldif"       />

Здесь явно указывается, что сервер LDAP должен загрузить свое содержимое из файла users.ldif, находящегося в корне библиотеки классов. Для наиболее любопытных в листинге 10.6 приводится со- держимое используемого здесь файла LDIF.

Листинг 10.6. Пример файла LDIF, где хранится информация для сервера LDAP

dn: ou=groups,dc=habuma,dc=com objectclass:    top

objectclass:  organizationalUnit ou: groups

dn: ou=people,dc=habuma,dc=com objectclass:    top

objectclass:  organizationalUnit ou: people

dn: uid=habuma,ou=people,dc=habuma,dc=com objectclass:    top

objectclass: person

objectclass:  organizationalPerson objectclass: inetOrgPerson

cn: Craig Walls sn: Walls

uid: habuma userPassword: password

dn:   uid=jsmith,ou=people,dc=habuma,dc=com objectclass:   top

objectclass: person

objectclass:  organizationalPerson objectclass: inetOrgPerson

1 Более подробное описание формата LDIF можно найти по адресу: http:// tools.ietf.org/html/rfc2849 (не менее подробное описание на русском языке можно найти по адресу: http://pro-ldap.ru/tr/zytrax/ch8/ – прим. перев.).

cn: John Smith sn: Smith    uid:   jsmith

userPassword: password

dn: cn=spitter,ou=groups,dc=habuma,dc=com objectclass:    top

objectclass:  groupOfNames cn:   spitter

member:    uid=habuma,ou=people,dc=habuma,dc=com

Независимо от того, как выполняется аутентификация – с по- мощью базы данных или сервера LDAP, для пользователя гораздо удобнее вообще не сталкиваться с процедурой аутентификации не- посредственно. Поэтому далее посмотрим, как настроить фреймворк Spring Security, чтобы он запоминал пользователя и не заставлял его выполнять процедуру аутентификации при каждом посещении приложения.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии