Я пытаюсь создать приложение безопасности 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. Любой ответ будет благодарен.
Спасибо за ваш ответ. Вы имеете в виду, в какой части моего источника есть ПЛОХАЯ вещь? Маршрутизатор или веб-клиент? Пожалуйста, сообщите мне справочный сайт, а также мои ошибки.
ваш сервис — publisher, все клиенты, звонящие вам, — subscribers. Так что не стоит использовать subscribe
вы никогда не должны /route/user/login/{username}/{password} это отправит имена пользователей и пароли через Интернет бесплатно для всех, чтобы увидеть security.stackexchange.com/questions/142695/…





Аутентификация 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") теперь устарел.
у вас есть несколько плохих вещей в вашем коде, вы НИКОГДА не подписываетесь в приложении webflux, поэтому все
subscribeнужно удалить. И я понятия не имею, что у вас за вопрос. Когда люди звонят в вашу службу или когда ваша служба звонит в другую службу?