0
votes

I am using Spring webflux security for my application and trying to write Spring webflux restdocs. Getting unauthorized error for test cases. Is there anyway to by pass security for rest doc test cases? Is it possible to control thru property?

@ExtendWith({ SpringExtension.class, RestDocumentationExtension.class })
@WebFluxTest({ RegistrationRequesttHandler.class })
@AutoConfigureWebTestClient(timeout = "100000")
class RegistrationRequestHandlerTest {

    @Autowired
    ApplicationContext context;

    @MockBean
    private OrgRepository orgRepository;

    @MockBean
    private UserRepository usrRepository;

    @Captor
    private ArgumentCaptor<Organization> orgInputCaptor;

    @Captor
    private ArgumentCaptor<Mono<Organization>> orgMonoInputCaptor;

    @Captor
    private ArgumentCaptor<User> usrInputCaptor;

    private WebTestClient webTestClient;

    @BeforeEach
    void setUp(RestDocumentationContextProvider restDocumentation) {
        webTestClient = WebTestClient.bindToApplicationContext(context).configureClient()
                .filter(documentationConfiguration(restDocumentation)).responseTimeout(Duration.ofMillis(100000))
                .build();
    }

    @Test
    public void testRegister() {

        final Register register = new Register();
        final Organization org = new Organization();
        final User usr = new User();

        given(orgRepository.save(orgInputCaptor.capture())).willReturn(Mono.just(org));
        given(usrRepository.save(usrInputCaptor.capture())).willReturn(Mono.just(usr));

        webTestClient.mutateWith(csrf()).post().uri(REGISTER_PATH).contentType(APPLICATION_JSON).bodyValue(register).exchange()
                .expectStatus().is2xxSuccessful().expectBody();

        StepVerifier.create(orgMonoInputCaptor.getValue()).expectNext(org).expectComplete();

        then(usrRepository).should().save(usrInputCaptor.capture());

    }

    private String buildRegister() {
        // TODO Auto-generated method stub
        return null;
    }

}

Here, I am testing /register api which is been set to permitAll().

@Bean
    public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
        return http.authorizeExchange().matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                .pathMatchers("/register", "/login").permitAll()
                .anyExchange().authenticated()
                .and().formLogin()
                .securityContextRepository(securityContextRepository())
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.BAD_REQUEST))
                .and().csrf().disable()
                .build();
    }

But still getting 401 error for testRegister. Do we need to create test bean for SecurityWebFilterChain also with permitAll for register API?

1
Spring Security's testing documentation describes a number of options that you could use: docs.spring.io/spring-security/site/docs/current/reference/… - Andy Wilkinson

1 Answers

0
votes

By default, spring-security enabled for Test classes, in order to test public APIs we have to skip security by excluding AutoConfiguration.

@ExtendWith(SpringExtension.class)
@WebFluxTest(controllers = AuthController.class, excludeAutoConfiguration = ReactiveSecurityAutoConfiguration.class)
public class AuthControllerTest {

@Autowired
private WebTestClient webClient;

@MockBean
AuthService authService;

 @Test
public void shouldSignUp() {

    UserDto userDto = UserDto.builder()
            .firstName("firstName")
            .lastName("lastName")
            .phone("phone")
            .password("password")
            .email(TEST_EMAIL)
            .role(UserRoles.ADMIN)
            .build();

    when(authService.signup(any(UserDto.class))).thenReturn(Mono.just(userDto));

    webClient
            .post().uri("/auth/v1/signup")
            .bodyValue(userDto)
            .exchange()
            .expectStatus()
            .isOk()
            .expectBody(UserDto.class);
  }
}

https://github.com/Brajendra/springboot-reactive-starter-kit