Где указать имя пользователя и пароль WebClient Spring Webflux?

Я пытаюсь создать приложение безопасности spring webflux с классами маршрутизатора и обработчика. Во-первых, ниже приведены коды конфигурации безопасности webflux.

@Configuration
@EnableWebFluxSecurity
public class BlogWebFluxSecurityConfig {

    @Bean
    public MapReactiveUserDetailsService userDetailsService() {

        UserDetails userWebFlux = User.withUsername("joseph").password("password").roles("USER").build();
        return new MapReactiveUserDetailsService(userWebFlux);
    }

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
        .authorizeExchange()
        .pathMatchers("/route/user/all", "/route/post/all").permitAll()
        .pathMatchers(HttpMethod.GET, "/route/user/**", "/route/post/**").hasRole("USER")
        .anyExchange().authenticated()
        .and()
        .httpBasic();

        return http.build();
    } 
}

А следующие коды относятся к классу роутера.

@Configuration
@EnableWebFlux
public class BlogWebFluxEndpointRouter {

    @Bean
    public RouterFunction<ServerResponse> routesUser(UserHandler handler) {

        return RouterFunctions.route(RequestPredicates.GET("/route/user/all"), handler::findAll)
                    .andRoute(RequestPredicates.GET("/route/user/id/{id}"), handler::findById)
                    .andRoute(RequestPredicates.GET("/route/user/username/{username}"), handler::findByUsername)
                    .andRoute(RequestPredicates.GET("/route/user/email/{email}"), handler::findByEmail)
                    .andRoute(RequestPredicates.POST("/route/user/create"), handler::register)
                    .andRoute(RequestPredicates.GET("/route/user/login/{username}/{password}"), handler::authenticate);
    }

    @Bean
    public RouterFunction<ServerResponse> routesPost(PostHandler handler) {

        return RouterFunctions.route(RequestPredicates.GET("/route/post/all"), handler::findAll)
                    .andRoute(RequestPredicates.GET("/route/post/id/{id}"), handler::findById)
                    .andRoute(RequestPredicates.GET("/route/post/delete/{id}"), handler::deleteById)
                    .andRoute(RequestPredicates.POST("/route/post/create"), handler::create)
                    .andRoute(RequestPredicates.PUT("/route/post/{id}/{content}"), handler::edit);
    }
}

Даже сеть - это остальная веб-служба, но я использую класс WebClient WebFlux.

public void functionOnUserDocument() { 
        client.get().uri("/route/user/all").accept(MediaType.APPLICATION_JSON).exchange()
                .flatMapMany(response -> response.bodyToFlux(User.class))
                .subscribe(u -> System.out.println("All Users : " + u.getUsername() + ":" + u.getEmail() + ":" + u.getFullname()));

        client.get().uri("/route/user/id/{id}", "0002").accept(MediaType.APPLICATION_JSON).exchange()
                .flatMap(response -> response.bodyToMono(User.class))
                .subscribe(u -> System.out.println("GET by Id : " + u.getUsername() + ":" + u.getEmail() + ":" + u.getFullname()));

        client.get().uri("/route/user/username/{username}", "jina").accept(MediaType.APPLICATION_JSON).exchange()
                .flatMap(response -> response.bodyToMono(User.class))
                .subscribe(u -> System.out.println("Get by username : " + u.getUsername() + ":" + u.getEmail() + ":" + u.getFullname()));

        client.get().uri("/route/user/email/{email}", "[email protected]").accept(MediaType.APPLICATION_JSON).exchange()
                .flatMap(response -> response.bodyToMono(User.class))
                .subscribe(u -> System.out.println("Get By Email : " + u.getUsername() + ":" + u.getEmail() + ":" + u.getFullname()));

        client.get().uri("/route/user/login/{username}/{password}", "julian", "password").exchange()
                .map(ClientResponse::statusCode).subscribe(response -> System.out.println("Login : " + response.getReasonPhrase()));

        User user = new User("0005", 4L, "jane", "password", "[email protected]", "누나", "USER");

        client.post().uri("/route/user/create").body(Mono.just(user), User.class).exchange() 
                .map(ClientResponse::statusCode).subscribe(response -> System.out.println("User Creation: " + response.getReasonPhrase()));
    }

Поскольку я делаю конфигурацию безопасности webflux, определенно некоторые веб-клиенты не могут быть выполнены и запрещены, как показано ниже,

Login : Unauthorized
User Creation: Forbidden

Я не использую завиток. Итак, что я хочу знать, так это то, какими должны быть мои методы WebClient, где имя пользователя и пароль должны быть расположены и переданы в класс WebClient. Любой ответ будет благодарен.

у вас есть несколько плохих вещей в вашем коде, вы НИКОГДА не подписываетесь в приложении webflux, поэтому все subscribe нужно удалить. И я понятия не имею, что у вас за вопрос. Когда люди звонят в вашу службу или когда ваша служба звонит в другую службу?

Toerktumlare 05.07.2019 20:56

Спасибо за ваш ответ. Вы имеете в виду, в какой части моего источника есть ПЛОХАЯ вещь? Маршрутизатор или веб-клиент? Пожалуйста, сообщите мне справочный сайт, а также мои ошибки.

Joseph Hwang 05.07.2019 22:59

ваш сервис — publisher, все клиенты, звонящие вам, — subscribers. Так что не стоит использовать subscribe

Toerktumlare 05.07.2019 23:05

вы никогда не должны /route/user/login/{username}/{password} это отправит имена пользователей и пароли через Интернет бесплатно для всех, чтобы увидеть security.stackexchange.com/questions/142695/…

Toerktumlare 05.07.2019 23:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
7 765
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Аутентификация HTTP Basic предполагает, что имя пользователя и пароль будут закодированы в формате Base64 в заголовке Authorization. Кроме того, вам не нужно иметь конечную точку входа, поскольку эта информация должна отправляться с каждым запросом.

Добавьте заголовок Basic Auth к каждому вызову в вашем клиенте, как показано ниже:

String basicAuthHeader = "basic " + Base64Utils.encodeToString((username + ":" + password).getBytes())

client.get().uri("/route/user/all")
      .accept(MediaType.APPLICATION_JSON)
      .header(HttpHeaders.AUTHORIZATION, basicAuthHeader)
      .exchange()
      .flatMapMany(response -> response.bodyToFlux(User.class))
      .subscribe(u -> System.out.println("All Users : " + u.getUsername() + ":" + u.getEmail() + ":" + u.getFullname()));

Spring предоставляет API для предоставления основных параметров аутентификации вашему веб-клиенту через Клиентские фильтры.

Вы можете добиться того же результата, настроив заголовок Authorization с меньшим количеством пользовательского кода.

Пожалуйста, смотрите фрагмент кода ниже из весенних документов:

import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;

    WebClient client = WebClient.builder()
            .filter(basicAuthentication("user", "password"))
            .build();

Начиная с весны 5.1 вы должны установить базовую аутентификацию с помощью HttpHeaders#setBasicAuth, например:

webClient
    .get()
    .uri("https://example.com")
    .headers(headers -> headers.setBasicAuth("username", "password"))
    .exchange()
    ....

предыдущий подход с использованием .filter(basicAuthentication("user", "password") теперь устарел.

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