1. Общ преглед
LDAP сървърите на директории са оптимизирани за четене йерархични хранилища на данни. Обикновено те се използват за съхраняване на свързана с потребителя информация, необходима за удостоверяване и упълномощаване на потребителя.
В тази статия ще проучим Spring LDAP API за удостоверяване и търсене на потребители, както и за създаване и модифициране на потребители в сървъра на директории. Същият набор от API може да се използва за управление на всякакъв друг вид записи в LDAP.
2. Зависимости на Maven
Нека започнем с добавяне на необходимата зависимост на Maven:
org.springframework.ldap spring-ldap-core 2.3.1.RELEASE
Последната версия на тази зависимост може да бъде намерена на spring-ldap-core.
3. Подготовка на данните
За целите на тази статия нека първо създадем следния LDAP запис:
ou=users,dc=example,dc=com (objectClass=organizationalUnit)
Под този възел ще създадем нови потребители, ще модифицираме съществуващи потребители, ще удостоверим съществуващите потребители и ще търсим информация.
4. Пролетни API на LDAP
4.1. ContextSource & LdapTemplate Bean Definition
ContextSource се използва за създаване на LdapTemplate . Ще видим използването на ContextSource по време на удостоверяване на потребителя в следващия раздел:
@Bean public LdapContextSource contextSource() { LdapContextSource contextSource = new LdapContextSource(); contextSource.setUrl(env.getRequiredProperty("ldap.url")); contextSource.setBase( env.getRequiredProperty("ldap.partitionSuffix")); contextSource.setUserDn( env.getRequiredProperty("ldap.principal")); contextSource.setPassword( env.getRequiredProperty("ldap.password")); return contextSource; }
LdapTemplate се използва за създаване и модифициране на LDAP записи:
@Bean public LdapTemplate ldapTemplate() { return new LdapTemplate(contextSource()); }
4.2. Удостоверяване на потребителя
Нека сега приложим проста логика за удостоверяване на съществуващ потребител:
public void authenticate(String username, String password) { contextSource .getContext( "cn=" + username + ",ou=users," + env.getRequiredProperty("ldap.partitionSuffix"), password); }
4.3. Създаване на потребител
След това нека създадем нов потребител и съхраним SHA хеш на паролата в LDAP.
По време на удостоверяването LDAP сървърът генерира SHA хеш на предоставената парола и я сравнява със съхранената:
public void create(String username, String password) { Name dn = LdapNameBuilder .newInstance() .add("ou", "users") .add("cn", username) .build(); DirContextAdapter context = new DirContextAdapter(dn); context.setAttributeValues( "objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" }); context.setAttributeValue("cn", username); context.setAttributeValue("sn", username); context.setAttributeValue ("userPassword", digestSHA(password)); ldapTemplate.bind(context); }
digestSHA () е персонализиран метод, който връща Base64 кодирания низ на SHA хеш на предоставената парола.
И накрая, методът bind () на LdapTemplate се използва за създаване на запис в LDAP сървъра.
4.4. Модификация на потребителя
Можем да модифицираме съществуващ потребител или запис със следния метод:
public void modify(String username, String password) { Name dn = LdapNameBuilder.newInstance() .add("ou", "users") .add("cn", username) .build(); DirContextOperations context = ldapTemplate.lookupContext(dn); context.setAttributeValues ("objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" }); context.setAttributeValue("cn", username); context.setAttributeValue("sn", username); context.setAttributeValue("userPassword", digestSHA(password)); ldapTemplate.modifyAttributes(context); }
Методът lookupContext () се използва за намиране на предоставения потребител.
4.5. Търсене на потребител
Можем да търсим съществуващи потребители с помощта на филтри за търсене:
public List search(String username) { return ldapTemplate .search( "ou=users", "cn=" + username, (AttributesMapper) attrs -> (String) attrs.get("cn").get()); }
В AttributesMapper се използва, за да получите желаната стойност атрибут от записите са намерени. Вътрешно Spring LdapTemplate извиква AttributesMapper за всички намерени записи и създава списък със стойностите на атрибутите.
5. Тестване
spring-ldap-test предоставя вграден LDAP сървър, базиран на ApacheDS 1.5.5. За да настроим вградения LDAP сървър за тестване, трябва да конфигурираме следния Spring bean:
@Bean public TestContextSourceFactoryBean testContextSource() { TestContextSourceFactoryBean contextSource = new TestContextSourceFactoryBean(); contextSource.setDefaultPartitionName( env.getRequiredProperty("ldap.partition")); contextSource.setDefaultPartitionSuffix( env.getRequiredProperty("ldap.partitionSuffix")); contextSource.setPrincipal( env.getRequiredProperty("ldap.principal")); contextSource.setPassword( env.getRequiredProperty("ldap.password")); contextSource.setLdifFile( resourceLoader.getResource( env.getRequiredProperty("ldap.ldiffile"))); contextSource.setPort( Integer.valueOf( env.getRequiredProperty("ldap.port"))); return contextSource; }
Нека тестваме нашия метод за търсене на потребители с JUnit:
@Test public void givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() { List users = ldapClient .search(SEARCH_STRING); assertThat(users, Matchers.containsInAnyOrder(USER2, USER3)); }
6. Заключение
В тази статия представихме Spring LDAP API и разработихме прости методи за удостоверяване на потребителя, търсене на потребители, създаване и модификация на потребител в LDAP сървър.
Както винаги пълният изходен код е наличен в този проект на Github. Тестовете се създават под профила на Maven „на живо“ и следователно могат да се изпълняват с помощта на опцията „-P на живо“.