问题描述
我正在为我的应用程序使用 Spring webflux 安全性并尝试编写 Spring webflux restdocs。获取测试用例的未经授权的错误。反正有没有绕过休息文档测试用例的安全性?可以通过财产来控制吗?
@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;
}
}
在这里,我正在测试设置为 permitAll() 的 /register api。
@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();
}
但仍然收到 testRegister 的 401 错误。我们是否需要为 SecurityWebFilterChain 创建测试 bean 并使用 permitAll 来注册 API?
解决方法
默认情况下,为测试类启用 spring-security,为了测试公共 API,我们必须通过排除 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