Java/Spring Boot中使用MockMvc测试带Authorization头的接口
MockMvc测试JWT授权接口的问题修复
问题诊断
你的代码存在三个核心问题导致JWT令牌无法生效:
- Authorization头格式错误:标准JWT认证头需要
Bearer前缀,直接返回令牌字符串会被Spring Security忽略 - 权限Claims处理错误:将权限转成JSON字符串存入JWT,不符合Spring Security对权限Claim的格式要求(通常为字符串数组),且未传入实际权限
- 权限参数未传递:
authorizationToken方法中的authorities参数未实际传入JWT的Claims中
修复后的代码
1. 修正JWT生成方法
private String buildToken(@Nonnull ApiClient.JwtData data) { String[] authorities = data.getAuthorities(); return JWT.create() .withSubject(data.getUserId()) .withIssuedAt(new Date()) .withClaim("name", data.getUsername()) .withClaim("fullname", data.getUserFullName()) .withClaim("userid", data.getUserId()) .withClaim("locale", Objects.requireNonNullElse(data.getLocale(), DEFAULT_LOCALE)) // 直接传入字符串数组作为authorities claim .withClaim("authorities", authorities) .sign(Algorithm.HMAC256(SECRET)); } protected String authorizationToken(String... authorities) { // 确保JwtData构造参数顺序匹配类定义 final var jwtData = new ApiClient.JwtData( "USER_ID", "USER_NAME", "USER_FULLNAME", "US-EN", authorities ); // 拼接标准Bearer前缀 return "Bearer " + buildToken(jwtData); }
2. MockMvc请求代码(无需修改,确保调用修正后的方法即可)
mockMvc.perform(post("/endpoint") .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .header("Authorization", authorizationToken(APP_AUTHORIZATION))) .andDo(print()).andExpect(status().is2xxSuccessful());
关键注意事项
- 确保
SECRET常量和Spring Security配置中的JWT签名密钥完全一致,否则令牌会验证失败 - 核对
ApiClient.JwtData的构造方法参数顺序,保证传入的参数和类字段一一对应 - 如果你的Spring Security配置中权限Claim的名称不是
authorities,需要同步修改withClaim中的key值
内容的提问来源于stack exchange,提问作者Marcos
相关产品推荐
相关产品推荐

