Как использовать аутентификацию LDAP в корпоративной среде

Я бы хотел, чтобы пользователи входили в мое приложение Spring-Boot со своей корпоративной комбинацией имени пользователя и пароля (чтобы я мог использовать аутентификацию AD и (возможно, также) использовать эту AD для запроса активных пользователей).

Итак, я сделал nslookup -type=srv _ldap._tcp.MY.DOMAIN, что привело к результату:

Server: Servername.MY.DOMAIN
Address: 1.1.1.1

_ldap._tcp.MY.DOMAIN       SRV service location
      priority             = 0
      weight               = 50
      port                 = 389
      svr hostname         = a_host.MY.DOMAIN
//... a few more of these
a_host.MY.DOMAIN  internet address = 5.5.5.5

Затем я использовал этот VBS:

set objSysInfo = CreateObject("ADSystemInfo")
set objUser = GetObject("LDAP://" & objSysInfo.UserName)
wscript.echo "DN: " & objUser.distinguishedName

который вернулся:

DN: CN=Lastname\, Firstname,OU=OU1,OU=OU2,OU=OU3,DC=MY,DC=DOMAIN

и теперь я попытался (как было предложено в первом ответе) настроить приложение Spring Boot, используя этот класс для этого входа со ссылкой на это сообщение:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/secure")
            .authorizeRequests()
            .anyRequest().fullyAuthenticated()
            .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("MY.COMPANY", "ldap://a_host.MY.DOMAIN:389");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
    }
}

К сожалению, когда я запускаю приложение и ввожу учетные данные своей компании в свой Spring-Boot-Security-Login-UI, я не могу войти в приложение. Кроме того, путь /secure недоступен через http://localhost:8080/secure (результат 404). Теперь, когда я включаю отладку для Spring-Boot-Security, я получаю следующий вывод при вставке своих учетных данных:

2018-12-17 11:47:12.793 DEBUG 13232 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /login at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-12-17 11:47:16.510 DEBUG 13232 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login at position 1 of 15 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-12-17 11:47:27.462 DEBUG 13232 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /login at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@28db75a9. A new one will be created.
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@28db75a9. A new one will be created.
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /login at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login at position 3 of 15 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /login at position 4 of 15 in additional filter chain; firing Filter: 'CsrfFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login at position 4 of 15 in additional filter chain; firing Filter: 'CsrfFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /login at position 5 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login at position 5 of 15 in additional filter chain; firing Filter: 'LogoutFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/logout'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] o.s.security.web.FilterChainProxy        : /login at position 6 of 15 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.security.web.FilterChainProxy        : /login at position 6 of 15 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/login'
2018-12-17 11:47:27.466 DEBUG 13232 --- [io-8080-exec-10] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
2018-12-17 11:47:27.466 DEBUG 13232 --- [nio-8080-exec-9] w.a.UsernamePasswordAuthenticationFilter : Request is to process authentication
2018-12-17 11:47:27.470 DEBUG 13232 --- [io-8080-exec-10] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2018-12-17 11:47:27.470 DEBUG 13232 --- [nio-8080-exec-9] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2018-12-17 11:47:27.534 DEBUG 13232 --- [io-8080-exec-10] o.s.s.a.dao.DaoAuthenticationProvider    : User '%my_user%' not found
2018-12-17 11:47:27.534 DEBUG 13232 --- [nio-8080-exec-9] o.s.s.a.dao.DaoAuthenticationProvider    : User '%my_user%' not found
2018-12-17 11:47:27.534 DEBUG 13232 --- [io-8080-exec-10] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Ung³ltige Anmeldedaten

org.springframework.security.authentication.BadCredentialsException: Ung³ltige Anmeldedaten
        at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:151) ~[spring-security-core-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
        at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-5.1.2.RELEASE.jar!/:5.1.2.RELEASE]
//...
2018-12-17 11:47:27.538 DEBUG 13232 --- [nio-8080-exec-9] w.a.UsernamePasswordAuthenticationFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Ung³ltige Anmeldedaten
org.springframework.security.authentication.BadCredentialsException: Ung³ltige Anmeldedaten

Так как он не находит моего пользователя (я также пробовал с именем пользователя@ДОМЕН, ДОМЕН\имя пользователя...), кажется, что я либо неправильно настроил url, либо использовал неправильную форму для вставки своих данных для входа (я использовал стартовую страницу, когда запуск приложения с помощью Spring-Boot-Security).

ОБНОВЛЕНИЕ:

Я убедился, что предоставленное имя пользователя %my_user% равно моему имени участника-пользователя, поэтому это похоже на проблему с конфигурацией, так как безопасность весенней загрузки говорит, что его невозможно найти.

ОБНОВЛЕНИЕ 2:

Я собираюсь обновить этот пост до самого окончательного решения, к которому мы пришли благодаря @GabrielLuci. Проблема решена :)


person Rüdiger    schedule 13.12.2018    source источник


Ответы (1)


В этой документации показана конфигурация для использования в... "обычном" каталоге LDAP (например, OpenLDAP). У Active Directory есть свои особенности, поэтому она ведет себя не совсем так, как остальной мир LDAP.

Spring имеет ActiveDirectoryLdapAuthenticationProvider только для этой цели. В этом ответе есть пример того, как использовать его в вашем классе WebSecurityConfig:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/secure")
            .authorizeRequests()
            .anyRequest().fullyAuthenticated()
            .and()
            .httpBasic();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
    }
    @Bean
    public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("adldap.company.com", "ldap://adldap.company.com");
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setUseAuthenticationRequestCredentials(true);
        return provider;
    }
}
person Gabriel Luci    schedule 13.12.2018
comment
Спасибо за ответ. Я попытался изменить свою конфигурацию и обновил свой вопрос :) - person Rüdiger; 17.12.2018
comment
У меня возникли проблемы с определением того, как должен выглядеть мой url. На данный момент я выбрал первую запись, которую я получил от этой команды nslookup (имя компьютера), и сделал следующее: ldap://computername.my.domain:389 - без предоставления и OC или что-то в этом роде. Это правильно? - person Rüdiger; 17.12.2018
comment
Достаточно просто ldap://my.domain (можно указать имя компьютера контроллера домена, но в этом нет необходимости. Кроме того, порт по умолчанию для LDAP — 389, поэтому указывать его не нужно. - person Gabriel Luci; 17.12.2018
comment
документация говорит, что поисковый фильтр по умолчанию использует userPrincipalName (обычно [email protected]). Если вы хотите изменить это, чтобы использовать обычное имя пользователя (sAMAccountName), вы можете позвонить provider.setSearchFilter(). Я обновил свой код с этим. - person Gabriel Luci; 17.12.2018
comment
К сожалению, результат тот же — хорошо, я никогда не думал об этом, но позвольте мне попытаться объяснить, что я хочу сделать: в нашей корпорации мы входим, например, в Outlook с комбинацией сокращений и паролей. Кроме того, эти сокращения сопоставляются с почтовыми адресами ([email protected]) — теперь, что такое userPrincipleName? Судя по документации это AD-CN? Мой сценарий, который я выполняю в своем посте, говорит мне как CN lastname,\ firstname, разве это не должно быть сокращением, которое я использую для аутентификации (или хочу использовать)? - person Rüdiger; 17.12.2018
comment
userPrincipalName — это имя фактического атрибута в AD. Если вы посмотрите на пользователя в разделе «Пользователи и компьютеры AD» на вкладке «Учетная запись», это имя пользователя для входа вверху (в этом окне оно разделено на две части). Он может совпадать с адресом электронной почты, но не обязательно. (хотя, если вы используете Office 365, он должен совпадать с адресом электронной почты) - person Gabriel Luci; 17.12.2018
comment
Давайте продолжим обсуждение в чате. - person Gabriel Luci; 17.12.2018