You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试Spring Security OAuth2资源服务器配置?单元与集成测试解析

针对Spring Security OAuth2资源服务器配置的测试方案

一、如何测试该配置(无需依赖外部认证服务器)

因为无法控制认证服务器,核心思路是模拟JWT令牌与认证上下文,完全脱离外部认证服务,适配CI与开发环境:

1. 用Spring Security Test快速验证权限规则

借助MockMvc和Spring Security提供的JWT模拟工具,直接构造不同权限的认证请求,验证端点的访问控制逻辑:

@SpringBootTest
@AutoConfigureMockMvc
class SecurityConfigTest {

    @Autowired
    private MockMvc mockMvc;

    // 测试私有端点:拥有api:read权限可访问
    @Test
    void privateEndpoint_WithReadScope_ShouldAllow() throws Exception {
        mockMvc.perform(get("/api/v1/private/data")
                        .with(jwt().authorities(new SimpleGrantedAuthority("SCOPE_api:read"))))
                .andExpect(status().isOk());
    }

    // 测试私有端点:无对应权限被拒绝
    @Test
    void privateEndpoint_WithoutValidScope_ShouldDeny() throws Exception {
        mockMvc.perform(get("/api/v1/private/data")
                        .with(jwt().authorities(new SimpleGrantedAuthority("SCOPE_other:read"))))
                .andExpect(status().isForbidden());
    }

    // 测试公共端点:已认证用户可访问
    @Test
    void publicEndpoint_WithValidJwt_ShouldAllow() throws Exception {
        mockMvc.perform(get("/api/v1/public/info")
                        .with(jwt())) // 模拟已认证用户
                .andExpect(status().isOk());
    }

    // 测试公共端点:未认证用户被拒绝
    @Test
    void publicEndpoint_WithoutAuth_ShouldDeny() throws Exception {
        mockMvc.perform(get("/api/v1/public/info"))
                .andExpect(status().isUnauthorized());
    }
}

这里的jwt()是Spring Security Test提供的请求处理器,能快速构造认证上下文,无需真实JWT签名或认证服务器交互。

2. 自定义JWT解码器(适配严格校验场景)

如果需要验证JWT的签名、issuer等规则,可以在测试配置中替换默认解码器为模拟实现:

@TestConfiguration
static class TestSecurityConfig {
    @Bean
    JwtDecoder jwtDecoder() {
        // 模拟JWT解码逻辑,忽略签名验证,直接返回预设权限的JWT对象
        return token -> Jwt.withTokenValue(token)
                .header("alg", "none")
                .claim("scope", "api:read")
                .build();
    }
}

将该配置类通过@Import加入测试,即可模拟真实的JWT解析流程,同时避免依赖外部服务。

二、测试内容与单元/集成测试边界

1. 核心测试内容

  • 端点权限匹配:验证每个端点对应的权限规则是否生效(比如/api/v1/private/**必须拒绝无api:read/write权限的请求)
  • 认证状态校验:确认未认证用户无法访问公共端点,已认证用户可正常访问
  • 禁用认证方式验证:验证httpBasic、formLogin等已被禁用(比如发送httpBasic请求应返回401,而非跳转登录页)
  • 方法级权限校验:如果Controller方法使用了@PreAuthorize等注解,需单独验证这些注解的规则是否生效

2. 单元测试与集成测试的边界

  • 单元测试:聚焦SecurityConfig本身的配置逻辑,验证HttpSecurity的调用链是否符合预期,比如是否正确设置了权限规则、禁用了指定认证方式。可以用Mockito模拟HttpSecurity对象:
class SecurityConfigUnitTest {

    private SecurityConfig securityConfig = new SecurityConfig();

    @Test
    void filterChain_ConfiguresCorrectRules() throws Exception {
        HttpSecurity http = mock(HttpSecurity.class);
        AuthorizationManagerRequestMatcherRegistry authRegistry = mock(AuthorizationManagerRequestMatcherRegistry.class);
        
        when(http.authorizeRequests()).thenReturn(authRegistry);
        when(authRegistry.antMatchers("/api/v1/private/**")).thenReturn(mock(AuthorizationManagerRequestMatcherRegistry.AuthorizedUrl.class));
        
        securityConfig.filterChain(http);
        
        // 验证配置逻辑是否正确执行
        verify(authRegistry).antMatchers("/api/v1/private/**");
        verify(authRegistry).antMatchers("/api/v1/public/**");
        verify(http).oauth2ResourceServer(any());
        verify(http).httpBasic().disable();
    }
}
  • 集成测试:验证Spring上下文加载后,Security配置与Controller、过滤器等组件的协同工作是否正常,也就是通过MockMvc测试真实端点的请求结果,对应第一部分的测试方案。集成测试不关心HttpSecurity的内部调用,只关注实际请求的权限控制结果是否符合预期。

内容的提问来源于stack exchange,提问作者Dmytro Chasovskyi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:55:16