SpringBoot2 + Webflux - WebTestClient always returns “401 UNAUTHORIZED”

Viewed 4633

I am trying to write some test using WebTestClient under Springboot 2.1.8 and Junit5

It's always returning < 401 UNAUTHORIZED Unauthorized, but actually it didn't go to the controller or service layer at all. It may related to spring security, just my guess.

The project was generated using JHipster. Here is the build.gradle

-----------------UimApiServiceImplTest.java-------------------

...


@ExtendWith(SpringExtension.class)
@WebFluxTest(controllers = UserGuidController.class)
@ContextConfiguration(classes = {UserGuidController.class, UimApiServiceImpl.class})

public class UimApiServiceImplTest {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    public void testGetGuidByEmail() {

        webTestClient.get()
            .uri("/uimapi/getguid/{email}", "someone@xxxxx.com")
            .accept(MediaType.APPLICATION_JSON_UTF8)
            .exchange()
            .expectStatus().isOk();
    }
}

--------------------UserGuidController.java--------------------

...
@RestController
@RequestMapping("/uimapi")
public class UserGuidController {

    @Autowired
    private UimApiServiceImpl uimApiService;

    private static final Logger logger = LoggerFactory.getLogger(UserGuidController.class);

    @GetMapping("/getguid/{email}")
    public String getUserGuid(@PathVariable String email) {
        return uimApiService.getUserGuid(email);
    }
}
2 Answers

For webflux, you can disable SecurityAutoconfiguration by excluding the ReactiveSecurityAutoConfiguration class like this:

@WebFluxTest(controllers = YourController.class,excludeAutoConfiguration = {ReactiveSecurityAutoConfiguration.class}))

You've implementation "org.springframework.boot:spring-boot-starter-security" in your gradle dependencies. Spring boot automatically enables security on all endpoints by default when this dependency is found in classpath.

You can choose to disable this default configuration by updating your main class:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })

This would disable security on all endpoints.

If you want to have control of which endpoints to remove security from, you can do that using the below code with updates matching your requirements:

@Configuration
public class SecurityConfiguration {

  @Bean
  public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
    http.authorizeExchange().anyExchange().permitAll();
    return http.build();
  }
}
Related