В предыдущем примере пароли шифруются с помощью функции хэширования паролей bcrypt. Это предполагает, что пароли также зашифрованы с помощью bcrypt на сервере LDAP.
ОБРАЩЕНИЕ К УДАЛЕННОМУ СЕРВЕРУ LDAP
Единственное, я до сих пор так и не указал местоположение, где находится LDAP-сервер и на котором нужные данные фактически находяться. Вы успешно настроили Spring для аутентификации на сервере LDAP, но где этот сервер?
По умолчанию аутентификация LDAP Spring Security предполагает, что сервер LDAP прослушивает порт 33389 на localhost. Но если ваш сервер LDAP находится на другой машине, вы можете использовать метод contextSource() для настройки его местоположения:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchBase("ou=people")
.userSearchFilter("(uid={0})")
.groupSearchBase("ou=groups")
.groupSearchFilter("member={0}")
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("passcode")
.contextSource()
.url("ldap://tacocloud.com:389/dc=tacocloud,dc=com");
}
Метод contextSource() возвращает ContextSourceBuilder, который, помимо прочего, предлагает метод url(), позволяющий указать расположение сервера LDAP.
НАСТРОЙКА ВСТРОЕННОГО СЕРВЕРА LDAP
Если у вас нет сервера LDAP, ожидающего аутентификации, Spring Security может предоставить вам встроенный сервер LDAP. Вместо установки URL-адреса удаленного сервера LDAP можно указать корневой суффикс для встроенного сервера с помощью метода root():
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchBase("ou=people")
.userSearchFilter("(uid={0})")
.groupSearchBase("ou=groups")
.groupSearchFilter("member={0}")
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("passcode")
.contextSource()
.root("dc=tacocloud,dc=com");
}
Когда сервер LDAP запустится, он попытается загрузить данные из любых LDIF-файлов, которые он может найти в пути к классам. LDIF (формат обмена данными LDAP) - это стандартный способ представления данных LDAP в текстовом файле. Каждая запись состоит из одной или нескольких строк, каждая из которых содержит имя и значение. Записи отделяются друг от друга пустыми строками.
Если вы предпочитаете, чтобы Spring не рылась в вашем classpath в поисках любых LDIF-файлов, которые он может найти, вы можете более четко указать, какой LDIF-файл загружается, вызвав метод ldif():
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchBase("ou=people")
.userSearchFilter("(uid={0})")
.groupSearchBase("ou=groups")
.groupSearchFilter("member={0}")
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("passcode")
.contextSource()
.root("dc=tacocloud,dc=com")
.ldif("classpath:users.ldif");
}
Здесь вы специально просите сервер LDAP загрузить его содержимое о пользователях. ldif-файл в корне classpath приложения. Если вам интересно, вот файл LDIF, который вы можете использовать для загрузки встроенного сервера LDAP с пользовательскими данными:
dn: ou=groups,dc=tacocloud,dc=com
objectclass: top
objectclass: organizationalUnit
ou: groups
dn: ou=people,dc=tacocloud,dc=com
objectclass: top
objectclass: organizationalUnit
ou: people
dn: uid=buzz,ou=people,dc=tacocloud,dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Buzz Lightyear
sn: Lightyear
uid: buzz
userPassword: password
dn: cn=tacocloud,ou=groups,dc=tacocloud,dc=com
objectclass: top
objectclass: groupOfNames
cn: tacocloud
member: uid=buzz,ou=people,dc=tacocloud,dc=com
Spring Security’s built-in хранилища пользователей удобны и покрывают некоторые общие случаи использования. Но приложение Taco Cloud нуждается в чем-то особенном. Если готовые пользовательские хранилища не соответствуют вашим потребностям, вам потребуется создать и настроить собственную службу сведений о пользователе.
4.2.4 Собственная служба сведений о пользователе
В последней главе вы остановились на использовании Spring Data JPA в качестве опции сохранения для всех данных taco, ingredient и order. Таким образом, было бы целесообразно сохранить пользовательские данные таким же образом. Если вы сделаете это, данные будут в конечном счете находиться в реляционной базе данных, поэтому вы можете использовать аутентификацию на основе JDBC. Но было бы еще лучше использовать хранилище данных Spring, используемое для хранения пользователей.