Spring security 如何在webflux security的webclient上的HTTP.POST和HTTP.PUT上添加HTTP基本身份验证?

Spring security 如何在webflux security的webclient上的HTTP.POST和HTTP.PUT上添加HTTP基本身份验证?,spring-security,spring-webflux,Spring Security,Spring Webflux,我尝试制作一些webflux安全代码,如下所示 @Configuration @EnableWebFluxSecurity public class BlogWebFluxSecurityConfig { @Bean public MapReactiveUserDetailsService userDetailsService() { UserDetails userWebFlux = User.withUsername("joseph").password(

我尝试制作一些webflux安全代码,如下所示

@Configuration
@EnableWebFluxSecurity
public class BlogWebFluxSecurityConfig {

    @Bean
    public MapReactiveUserDetailsService userDetailsService() {

        UserDetails userWebFlux = User.withUsername("joseph").password(passwordEncoder().encode("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();
    } 

    @Bean 
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
Login : Forbidden
User Creation: Forbidden
并使用WebClient类编写webflux客户端代码。我使用http基本身份验证。在HTTP GET方法中,HTTP基本身份验证工作成功。这些是webclient代码,它运行良好

client.get().uri("/route/post/id/{id}", 10).accept(MediaType.APPLICATION_JSON)
                .header(HttpHeaders.AUTHORIZATION, basicAuthHeader).exchange()
                .flatMap(response -> response.bodyToMono(Post.class))
                .subscribe(p -> System.out.println("GET by Id : " + p.getUser().getUsername() + ":" + p.getTitle()));
但是在HTTP.POST和HTTP.PUT方法上,HTTP基本身份验证不起作用,甚至抛出异常

public class WebFluxBlogClient {

    private WebClient client = WebClient.create("http://localhost:8080");  

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

    public void functionOnSecurityDocument() {

        Map<String, String> mapUser = new HashMap<String, String>();
        mapUser.put("username", "joseph");
        mapUser.put("password", "password");

        client.post().uri("/route/user/login").accept(MediaType.APPLICATION_JSON).body(Mono.just(mapUser), Map.class)
                .header(HttpHeaders.AUTHORIZATION, basicAuthHeader).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").accept(MediaType.APPLICATION_JSON).body(Mono.just(user), User.class)
                .header(HttpHeaders.AUTHORIZATION, basicAuthHeader).exchange() 
                .map(ClientResponse::statusCode).subscribe(response -> System.out.println("User Creation: " + response.getReasonPhrase()));


        client.put().uri("/route/post/{id}/{content}", 7, "test sentences....")
                .accept(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, basicAuthHeader).exchange().flatMap(response -> response.bodyToMono(Post.class))
                .subscribe(p -> System.out.println("EDIT by Id : " + p.getUser().getUsername() + ":" + p.getBody()));
    }
}
我不知道例外的含义。我想知道如何在webflux webclient的http.POST和http.PUT方法上应用http基本身份验证

更新部分 我更改了如下的安全配置,但失败了

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

        return http.build();
    }
为供您参考,我附上路由器类

@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.POST("/route/user/login"), handler::authenticate);
    }

我的SecurityWebFilterChain配置有一些问题?

您明确限制身份验证仅获取请求。如果在
SecurityWebFilterChain
配置中替换此行:

.pathMatchers(HttpMethod.GET, "/route/user/**", "/route/post/**").hasRole("USER")
对于不包括HTTP方法的更通用的方法,auth应该应用于所有HTTP方法

.pathMatchers("/route/user/**", "/route/post/**").hasRole("USER")

您显式地将身份验证限制为仅获取请求。如果在
SecurityWebFilterChain
配置中替换此行:

.pathMatchers(HttpMethod.GET, "/route/user/**", "/route/post/**").hasRole("USER")
对于不包括HTTP方法的更通用的方法,auth应该应用于所有HTTP方法

.pathMatchers("/route/user/**", "/route/post/**").hasRole("USER")

该应用程序可能会给您一个403,因为它存在于具有副作用的请求中,如POST。Spring Security默认启用CSRF防御


您需要在POST请求中发送CSRF令牌,否则您需要发送。

应用程序可能会给您403,因为它在POST等有副作用的请求中。Spring Security默认启用CSRF防御


您需要在POST请求中发送CSRF令牌,否则您需要。

请查看我的更新部分好吗?我完全被困在这里了。你能看看我更新的部分吗?我完全被困在这里了。