测试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
相关产品推荐
相关产品推荐

