J'essaie de créer une application de sécurité Spring Webflux avec des classes de routeurs et de gestionnaires. Tout d'abord, les codes ci-dessous sont les codes de configuration de la sécurité webflux.
Login : Unauthorized User Creation: Forbidden
Et les codes suivants concernent la classe de routeur.
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}", "myson@college.ac.kr").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", "aaa@bbb.com", "ëë", "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())); }
Même le network est un service web de repos, mais j'utilise la classe WebClient de WebFlux.
@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); } }
Parce que je fais la configuration de sécurité webflux, certains webclient ne peuvent certainement pas être exécutés et interdits comme ci-dessous,
@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(); } }
Je n'utilise pas curl. Donc, ce que je veux savoir, c'est ce que doivent être mes méthodes WebClient, où le nom d'utilisateur et le mot de passe doivent être localisés et transférés vers la classe WebClient. Toute réponse sera reconnaissante.
3 Réponses :
L'authentification HTTP Basic attend le nom d'utilisateur et le mot de passe encodés au format Base64 dans l'en-tête Authorization
. De plus, vous n'avez pas besoin d'avoir un point de terminaison de connexion car ces informations doivent être envoyées avec chaque demande.
Ajoutez l'en-tête d'authentification de base à chaque appel dans votre client comme suit:
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 fournit une API pour fournir des paramètres d'authentification de base à votre client Web via ClientFilters .
Vous pouvez obtenir le même résultat en configurant l'en-tête Authorization
avec moins de codage personnalisé.
Veuillez consulter l'extrait de code ci-dessous tiré de la documentation du printemps:
import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication; WebClient client = WebClient.builder() .filter(basicAuthentication("user", "password")) .build();
Depuis le printemps 5.1, vous devez définir l'authentification de base avec HttpHeaders # setBasicAuth
, comme ceci:
webClient .get() .uri("https://example.com") .headers(headers -> headers.setBasicAuth("username", "password")) .exchange() ....
le approche précédente, consistant à utiliser .filter (basicAuthentication (" user "," password ")
, est désormais obsolète. p>
vous avez plusieurs mauvaises choses dans votre code, vous ne vous abonnez JAMAIS à une application webflux donc tout
abonnement
doit être supprimé. Et je n'ai aucune idée de votre question. Est-ce lorsque les gens appellent votre service ou lorsque votre service appelle un autre service?Merci pour votre réponse. Tu veux dire quelle partie de ma source a une mauvaise chose? Routeur ou WebClient? Veuillez m'informer du site de référence ainsi que de mes erreurs.
votre service est un
éditeur
, tous les clients qui l'appellent sont desabonnés
. Vous ne devez donc pas utilisersubscribe
vous ne devriez jamais
/ route / user / login / {username} / {password}
cela enverra gratuitement les noms d'utilisateur et les mots de passe sur Internet pour que tout le monde puisse les voir security.stackexchange.com / questions / 142695 /…