在Spring Boot 4.x中,与安全相关的行为与Spring Boot 3.x相比存在差异

后端开发 2026-07-12

根据我的观察更新了问题。

我在尝试理解Spring Security,在实现带有 @WebMvcTest 的测试时陷入困境。

我有一个Spring Boot 4.0.3项目,包含 spring-boot-starter-webmvc, spring-boot-starter-webmvc-test, spring-boot-starter-security 依赖。

spring-boot-starter-security-test 未包含。

没有与安全相关的配置。

下面是下方的REST控制器。

@RestController
public class DemoController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello";
    }
}

下面是测试类。

@WebMvcTest(DemoController.class)
@AutoConfigureRestTestClient
class DemoControllerTest {

    @Autowired
    private RestTestClient restClient;

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private MockMvcTester mockMvcTester;

    @Test
    void test_hello_001() {
        restClient.get()
                  .uri("/hello")
                  .exchange()
                  .expectStatus()
                  .isOk()
                  .expectBody(String.class)
                  .isEqualTo("Hello");
    }

    @Test
    void test_hello_002() {
        Assertions.assertThat(mockMvcTester.get()
                                           .uri("/hello"))
                  .hasStatusOk()
                  .hasBodyTextEqualTo("Hello");
    }

    @Test
    void test_hello_003() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
               .andExpect(MockMvcResultMatchers.status()
                                               .isOk())
               .andExpect(MockMvcResultMatchers.content()
                                               .string("Hello"));
    }
}

我还有一个Spring Boot 3.5.11项目,包含 spring-boot-starter-web, spring-boot-starter-test, spring-boot-starter-security 依赖。

spring-security-test 未包含。

没有与安全相关的配置。

下面是REST控制器。

@RestController
public class DemoController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello";
    }
}

下面是测试类。

@WebMvcTest(DemoController.class)
// @AutoConfigureRestTestClient
class DemoControllerTest {

    // @Autowired
    // private RestTestClient restClient;

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private MockMvcTester mockMvcTester;

    // @Test
    // void test_hello_001() {
    //     restClient.get()
    //               .uri("/hello")
    //               .exchange()
    //               .expectStatus()
    //               .isOk()
    //               .expectBody(String.class)
    //               .isEqualTo("Hello");
    // }

    @Test
    void test_hello_002() {
        Assertions.assertThat(mockMvcTester.get()
                                           .uri("/hello"))
                  .hasStatusOk()
                  .hasBodyTextEqualTo("Hello");
    }

    @Test
    void test_hello_003() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
               .andExpect(MockMvcResultMatchers.status()
                                               .isOk())
               .andExpect(MockMvcResultMatchers.content()
                                               .string("Hello"));
    }
}

test_hello_001 已被注释,因为 RestTestClient 不可用。

第一个项目(4.0.3)的测试在没有 @WithMockUser 或任何自定义安全配置的情况下通过。

当我在pom.xml中引入 spring-boot-starter-security-test 依赖时,测试会出现如下消息:

java.lang.AssertionError: Status expected:<200 OK> but was:<401 UNAUTHORIZED>
Expected :200 OK
Actual   :401 UNAUTHORIZED

第二个项目(3.5.11)的测试无论有无 spring-security-test 依赖都会失败。

对于第二个项目(3.5.11)的测试失败,这对我来说是合理的,添加 @WithMockUser 可以修复它。但为什么同样的测试在第一个项目(4.0.3)在没有 @WithMockUser 的情况下通过,添加 spring-boot-starter-security-test 依赖后就会失败呢。

解决方案

引入 spring-boot-starter-security-test 将最终拉入 spring-boot-security-test 模块。该模块包含安全部分的所有测试自动配置。

具体用于与 integration with @WebMvcTest 的集成。这些includes将在启动应用进行测试时引导安全部分。没有它,@WebMvcTest 就不会配置安全,因此测试将直接通过。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章