The following test should pass, as when I run my application, I'm correctly redirected to the /login page. But I cannot assert that in a junit test:
@SpringBootTest
@AutoConfigureMockMvc
public class AuthenticationTest {
@Autowired
private WebTestClient webTestClient;
@Test
public void testLoginPage() {
webTestClient.get()
.uri("/person")
.exchange()
.expectStatus().isFound() //fails due to status = 401 UNAUTHORIZED
.expectStatus().is3xxRedirection();
}
}
The full configuration is:
@Configuration
public class ReactiveSecurityConfiguration {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.anyExchange().authenticated()
.and().formLogin()
.and().httpBasic()
.and().build();
}
}
@RestController
public class PersonServlet {
@GetMapping("/person")
public Mono<Void> person() {
return Mono.empty();
}
}
@SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
}
artifacts:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Comment From: mhalbritter
You have to set the header Accept to text/html, otherwise the form login isn't triggered and the basic auth from your configuration steps in:
webTestClient.get()
.uri("/person")
.header("Accept", "text/html")
.exchange()
.expectStatus().isFound()
.expectStatus().is3xxRedirection()
works.
Comment From: mhalbritter
Labeling this as invalid, as it's not an issue, but a question which would be better suited for StackOverflow.
Comment From: crux
I have the kind of opposite situation. In real live (browser) spring returns 302. But with all tests it always returns 401. Accept set to text/html and various other attempt. Doesn't matter it sends a 401 in test. But sending a 302, in real life, to the browser, does lead to the browser not getting the hint it needs to even try the basic auth method, effectively failiing my basic auth URLs containing user:pass@server.com. (I know, this is the worst, but i inherited it, and it is legacy code, and I have to refactor it first, and contain it in a test suite bevor I can change behaviour)
WHY, and HOW is spring security controlling when it sends a 302 or a 401?
Comment From: mhalbritter
Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it). If you feel this is a genuine bug, please open a separate issue with a reproducer project. Thanks!
Comment From: crux
it would be a bug/issue, some place inside the mess of a framework the spring security package actually is. Once I might stumble on a place where I can tack, I will.
my comment was just ment as a short comment on someone having issues with the same things I have. Was not expecting any help here,
Comment From: wilkinsona
it would be a bug/issue, some place inside the mess of a framework the spring security package actually is
@crux This isn't helpful and it's neither constructive nor actionable. Please vent your frustration elsewhere.