hantsy / spring-reactive-sample

Spring 5/6 Reactive playground
https://hantsy.github.io/spring-reactive-sample/
GNU General Public License v3.0
1.32k stars 463 forks source link

Completed 403 FORBIDDEN in spring-reactive-sample-boot-data-mongo when doing post #7

Closed darmandovargas3 closed 6 years ago

darmandovargas3 commented 6 years ago

Hi dear Hantsy

Before all I want to thank you for this awesome collection of samples.

I'm working on the spring-reactive-sample-boot-data-mongo, my problem is with something I guess beyond the authentication, I know you have a portion of your documentation about it (https://github.com/hantsy/spring-reactive-sample#security-for-webflux) the thing is that no mater if I use your same curl with username and password of you sample, I always get this result in postman:

CSRF Token has been associated to this client

and in the backend I got this:

2018-11-21 22:07:28.968 DEBUG 46190 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter : [feb8e527] HTTP POST "/posts" 2018-11-21 22:07:28.974 DEBUG 46190 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter : [feb8e527] Completed 403 FORBIDDEN 2018-11-21 22:07:39.423 DEBUG 46190 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter : [feb8e527] HTTP DELETE "/posts/5bf616be20058db33b1939ad" 2018-11-21 22:07:39.425 DEBUG 46190 --- [ctor-http-nio-1] o.s.w.s.adapter.HttpWebHandlerAdapter : [feb8e527] Completed 403 FORBIDDEN

a bunch of Completed 403 FORBIDDEN messages, do you have an idea what is it ?

Thanks a lot for you time

Best Regards Diego Vargas

darmandovargas3 commented 6 years ago

Here is my call just for your information:

CSRF Token has been associated to this clientDiegos-MBP:engine-monitor-speedman-enterprise Diego$ curl -v -X POST http://localhost:8080/posts -u "admin:admin123" -H "Content-Type:application/json" -d "{\ My Post\"}"y Post\",\"content\":\"content of Note: Unnecessary use of -X or --request, POST is already inferred.

darmandovargas3 commented 6 years ago

Hi Hantsy I did add this " .csrf().disable()" to the springWebFilterChain, which got rid of the 403 issue, but, now always it returns 401, no matter what username and password I do define in userDetailsRepository and pass them to the curl command:

return http .csrf().disable() .authorizeExchange() .pathMatchers(HttpMethod.GET, "/posts/").permitAll() .pathMatchers(HttpMethod.DELETE, "/posts/").hasRole("ADMIN") .pathMatchers("/posts/").authenticated() //.pathMatchers("/users/{user}/").access(this::currentUserMatchesPath) .anyExchange().permitAll() .and() .build();

This is my UserDetailRepository:

@Bean public MapReactiveUserDetailsService userDetailsRepository() { UserDetails rob = User.withUsername("test").password("test123").roles("USER").build(); UserDetails admin = User.withUsername("admin").password("admin123").roles("USER", "ADMIN").build(); return new MapReactiveUserDetailsService(rob, admin); }

and this is my curl call:

curl -v -X POST http://localhost:8080/posts -u "admin:admin123" -H "Content-Type:application/json" -d "{\"title\":\"My Post\",\"content\":\"content of My Post\"}"

This is my response:

Diegos-MBP:engine-monitor-speedman-enterprise Diego$ curl -v -X POST http://localhost:8080/posts -u "admin:admin123" -H "Content-Type:application/json" -d "{\"title\":\"My Post\",\"content\":\"content of My Post\"}" Note: Unnecessary use of -X or --request, POST is already inferred.

darmandovargas3 commented 6 years ago

Hi Hantsy

I think I finally make it work in my local, I had to add not only .csrf().disable() but also this .httpBasic(), here is my SecurityConfig file:

`package com.example.demo;

import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.authorization.AuthorizationContext;

import reactor.core.publisher.Mono;

@EnableWebFluxSecurity class SecurityConfig {

@Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception {
    return http
            .csrf().disable()
            .authorizeExchange()
            .pathMatchers(HttpMethod.GET, "/posts/**").permitAll()
            .pathMatchers(HttpMethod.DELETE, "/posts/**").hasRole("ADMIN")
            .pathMatchers("/posts/**").authenticated()
            .anyExchange().permitAll()
            .and()
            .httpBasic()
            //.pathMatchers("/users/{user}/**").access(this::currentUserMatchesPath)

            .and()
            .build();
}

private Mono<AuthorizationDecision> currentUserMatchesPath(Mono<Authentication> authentication, AuthorizationContext context) {
    return authentication
            .map(a -> context.getVariables().get("user").equals(a.getName()))
            .map(granted -> new AuthorizationDecision(granted));
}

@Bean
public MapReactiveUserDetailsService userDetailsRepository() {
    UserDetails rob = User.withDefaultPasswordEncoder().username("test").password("test123").roles("USER").build();
    UserDetails admin = User.withDefaultPasswordEncoder().username("admin").password("admin123").roles("USER", "ADMIN").build();
    return new MapReactiveUserDetailsService(rob, admin);
}

}

`

Any suggestion about it is more than welcome, thanks a lot !

hantsy commented 6 years ago

@darmandovargas3 Yes, the newest Spring Security reactive added CSRF support. I will review the relative codes.