Spring Безопасность WebFlux и LDAP

Какие настройки необходимы для защиты приложения Reactive Spring Boot с помощью LDAP? Примеры, которые я видел до сих пор, основаны на Spring MVC, а пример защиты WebFlux показывает только простой пример Reactive с картой в памяти.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
8
0
2 746
2

Ответы 2

Вот одно из решений, которое я придумал и протестировал.

Особого внимания заслуживает эта информация в этом классе: ReactiveAuthenticationManagerAdapter. Там говорится:

Adapts an AuthenticationManager to the reactive APIs. This is somewhat necessary because many of the ways that credentials are stored (i.e. JDBC, LDAP, etc) do not have reactive implementations. What's more is it is generally considered best practice to store passwords in a hash that is intentionally slow which would block ever request from coming in unless it was put on another thread.

Сначала создайте класс конфигурации. Это будет обрабатывать подключение к LDAP.

@Configuration
public class ReactiveLdapAuthenticationConfig {

    // Set this in your application.properties, or hardcode if you want.
    @Value("${spring.ldap.urls}")
    private String ldapUrl;

    @Bean
    ReactiveAuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {

        BindAuthenticator ba = new BindAuthenticator(contextSource);
        ba.setUserDnPatterns(new String[] { "cn = {0},ou=people" } );

        LdapAuthenticationProvider lap = new LdapAuthenticationProvider(ba);

        AuthenticationManager am = new ProviderManager(Arrays.asList(lap));

        return new ReactiveAuthenticationManagerAdapter(am);

    }

    @Bean
    BaseLdapPathContextSource contextSource() {
        LdapContextSource ctx = new LdapContextSource();
        ctx.setUrl(ldapUrl);
        ctx.afterPropertiesSet();
        return ctx;
    }

}

После этого вы захотите настроить свою безопасность в соответствии с шаблонами здесь. Самая простая конфигурация цепочки примерно такая:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        .authorizeExchange()
            .anyExchange().authenticated()
            .and()
        .httpBasic();

    return http.build();
}

Для полноты картины убедитесь, что у вас есть:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-ldap</artifactId>
</dependency>

Другие ссылки

Приведенный выше пример не работал у меня с Windows Active Directory. Я мог заставить аутентификацию LDAP работать в автономном (не Spring) Java, но вышеупомянутое решение всегда выдавало мне ошибку 52e (пользователь известен, но неверный пароль).

Следуя приведенному выше примеру, я использовал те же pom.xml и @EnableWebFluxSecurity ... SecurityWebFilterChain(...), но со следующим;

@Configuration
public class ReactiveLdapAuthenticatoinConfig {

@Bean
ReactiveAuthenticationManager authenticationManager() {

   ActiveDirectoryLdapAuthenticationProvider adlap = 
      new ActiveDirectoryLdapAuthenticationProvider(
         "{my.domain}",
         "ldap://{my.ldap.server}.{my.domain}"
      );

   AuthenticationManager am = new ProviderManager(Arrays.asList(adlap));
   return new ReactiveAuthenticationManagerAdapter(am);
}
}

Чтобы вернуть вошедшего в систему пользователя, можно использовать что-то вроде:

@GetMapping(value = '/user')
public Mono<String> getUser(Mono<Principal> principal) {
   return principal.map(Principal::getName);
}

Другие вопросы по теме