Пролетен преглед на LDAP

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 на живо“.