【问题标题】:Spring Security testing Endpoint for user without specific role没有特定角色的用户的 Spring Security 测试端点
【发布时间】:2022-02-02 10:26:23
【问题描述】:

我正在为我的 Spring MVC 控制器编写一些集成测试。

控制器由 Spring Security 保护。

这是我目前的测试类:

@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.MOCK,
    classes = GuiBackendApplication.class
)
@AutoConfigureMockMvc
public class ConfigEditorControllerIntegrationTest {

    @Autowired
    private MockMvc mockedMvc;

    @Test
    @WithMockUser(username = "user", password = "password", roles = {"admin"})
    public void adminsCanAccessRuntimeConfig() throws Exception {

        this.mockedMvc.perform(get("/my/custom/api"))
            .andExpect(status().isOk());
    }
}

这个测试类确保管理员可以访问我的端点。它工作正常。

但是如果我想测试是否只有具有管理员角色的用户才能访问我的端点呢?

我可以编写一个测试,将@WithMockUsers 与我目前拥有的所有角色一起使用,除了管理员角色。但这会让我很难维持。我希望我的测试确保只有具有管理员角色的用户才能访问我的端点,而不管任何新角色。

我检查了 Spring Reference Docs 并没有找到任何相关信息。有没有办法做到这一点?

类似的东西

@Test
@WithMockUser(username = "user", password = "password", roles = {"IS NOT admin"})
public void nonAdminsCannotAccessRuntimeConfig() throws Exception {

    this.mockedMvc.perform(get("/my/custom/api"))
        .andExpect(status().isUnauthorized());
}

【问题讨论】:

  • 您的测试示例对我来说似乎是正确的。或者您是在询问 Spring Security 是否知道您的所有角色,并且可以生成一个将管理员角色转换为“所有其他可用角色”的测试?我不知道如何做到这一点,但我认为你不需要这样做。你能说更多为什么需要这样做吗?或者我没有正确理解你。
  • @SteveRiesenberg 是的,这就是我想要实现的目标。基本上,我想确保始终只有具有管理员角色的用户才能从我的端点获得响应。所以基本上,我希望 Spring 检查(模拟的)用户是否具有管理员角色,如果没有,控制器应该返回 401 状态代码。但是可能没有解决方案(比如我在最初的帖子中制作的角色 = {“IS NOT admin”} 草图)

标签: java spring spring-security spring-test spring-test-mvc


【解决方案1】:

Spring Security 不知道您的系统定义了哪些角色。因此,如果您想对所有可用角色有 100% 的测试覆盖率,就必须告诉它并一一测试。

您可以通过使用 JUnit 5 的 @ParameterizedTest 并将 MockMvc 配置为具有不同角色的 UserRequestPostProcessor 轻松地以维护方式完成此操作。

类似:

public class ConfigEditorControllerIntegrationTest {

    @ParameterizedTest
    @MethodSource
    public void nonAdminsCannotAccessRuntimeConfig(String role) throws Exception {
        mockedMvc.perform(get("/my/custom/api")
                 .with(user("someUser").roles(role)))
                 .andExpect(status().isUnauthorized());
    }

    static List<String> nonAdminsCannotAccessRuntimeConfig() {
        return Roles.exclude("admin");
    }
}

并创建一个类来维护所有可用的角色:

public class Roles {

    public static List<String> all() {
        return List.of("admin", "hr", "developer" , "accountant" , .... , "devops");
    }

    public static List<String> exclude(String excludeRole) {
        List<String> result = new ArrayList<>(all());
        result.remove(excludeRole);
        return result;
    }

}

【讨论】:

  • Spring 不必知道我的所有角色。它只需要在测试时知道用户是否具有管理员角色。但是感谢您提出的解决方案,这可能是我的问题的一个巧妙的解决方法:)
猜你喜欢
  • 2015-11-01
  • 2020-07-19
  • 2019-02-13
  • 2011-07-21
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
相关资源
最近更新 更多