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

测试Controller端点遇403错误,求WebSecurityConfig修改方案

问题分析与解决方案

核心问题

你的WebSecurityConfig配置的是OAuth2资源服务器(JWT认证模式),但测试代码使用@WithMockUser注解——这个注解是模拟传统的用户名密码会话认证,和JWT资源服务器的认证逻辑不兼容,导致Spring Security判定请求未通过合法认证,返回403。

解决步骤

1. 调整测试代码适配JWT认证

放弃@WithMockUser,改用适配JWT的测试方式:

  • 方式一:使用@WithMockJwt(Spring Security 5.6+支持)
    直接模拟JWT令牌,指定所需角色:

    @Test
    @WithMockJwt(claims = @JwtClaim(name = "roles", value = "ADMIN"))
    fun `testA`()  {
        mvc
            .perform(
                post("/bla/bla")
                    .contentType(MediaType.APPLICATION_JSON)
            ).andExpect(status().isCreated)
    }
    
  • 方式二:手动构造JWT并添加请求头
    若Spring Security版本较低,可手动生成测试用JWT,通过Authorization头传递:

    @Test
    fun `testA`()  {
        // 实现生成带ADMIN角色的测试JWT方法
        val testJwtToken = generateTestJwtWithAdminRole()
        
        mvc
            .perform(
                post("/bla/bla")
                    .header("Authorization", "Bearer $testJwtToken")
                    .contentType(MediaType.APPLICATION_JSON)
            ).andExpect(status().isCreated)
    }
    

2. 检查JWT角色转换逻辑

确认jwtAuthenticationConverter是否正确将JWT中的角色转换为Spring Security认可的格式:
hasRole("ADMIN")会自动给角色添加ROLE_前缀,所以转换器需要将JWT中的角色(比如"ADMIN")转换为ROLE_ADMIN,示例代码:

fun jwtAuthenticationConverter(): JwtAuthenticationConverter {
    val grantedAuthoritiesConverter = JwtGrantedAuthoritiesConverter()
    grantedAuthoritiesConverter.setAuthorityPrefix("ROLE_")
    grantedAuthoritiesConverter.setAuthoritiesClaimName("roles") // 对应JWT中存储角色的字段名

    val jwtConverter = JwtAuthenticationConverter()
    jwtConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter)
    return jwtConverter
}

3. 关于启用CSRF后的404问题

OAuth2资源服务器(JWT模式)属于无状态认证,通常不需要启用CSRF,保持csrf().disable()即可。启用CSRF后出现404,大概率是因为请求未携带有效CSRF令牌,或者端点/bla/bla本身定义有误(先确认Controller中是否存在该POST端点)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:50:33