Spring Boot REST服务如何将JUnit 5测试从Basic认证改为Keycloak OAuth2
原有测试适配OAuth2认证体系的修改方案
原有注入身份方案的兼容性说明
- 原
@WithUserDetails注解不能直接使用:该注解是基于用户名密码认证体系的UserDetailsService设计的,当前OAuth2资源服务器依赖的身份对象是JwtAuthenticationToken,和注解生成的UsernamePasswordAuthenticationToken类型不匹配,直接使用会触发401/403权限错误。 - 手动设置SecurityContext的方案可以调整后使用:只要手动构造符合要求的
JwtAuthenticationToken实例注入安全上下文就可以正常运行,不需要真实调用Keycloak申请令牌,适合单元测试场景。
具体修改方案
场景1:单元测试(仅测试Controller逻辑,不依赖Keycloak服务)
推荐使用Spring Security官方提供的模拟注解快速注入身份,不需要改动原有测试的业务逻辑:
- 确保已经引入
spring-security-test测试依赖,Spring Boot 2.7+版本的spring-boot-starter-test已经默认集成该依赖。 - 替换原有
@WithUserDetails("admin")注解为@WithMockJwtAuth,示例如下:
// 注解参数里的authorities和你自定义JWT权限转换器输出的角色格式保持一致即可 @WithMockJwtAuth(authorities = {"ROLE_admin"}, claims = @Claims(sub = "admin")) @Test void testAdminApi() { // 原有测试逻辑不需要修改 }
如果是原手动注入SecurityContext的场景,调整构造逻辑即可,示例代码:
// 1. 构造模拟JWT对象,匹配Keycloak返回的JWT结构 Jwt mockJwt = Jwt.withTokenValue("fake-token-123") .header("alg", "RS256") .claim("sub", "admin") .claim("realm_access", Map.of("roles", List.of("admin"))) .build(); // 2. 复用你自定义的JWT权限转换器生成权限集合 Collection<GrantedAuthority> authorities = customJwtGrantedAuthoritiesConverter.convert(mockJwt); // 3. 构造资源服务器识别的认证对象 JwtAuthenticationToken authentication = new JwtAuthenticationToken(mockJwt, authorities); // 4. 注入安全上下文 SecurityContextHolder.getContext().setAuthentication(authentication);
测试执行完成后记得清空SecurityContext,避免上下文污染其他测试用例。
场景2:集成测试(真实走OAuth2认证流程,依赖已启动的Keycloak服务)
完全模拟真实用户请求流程,适合端到端验证认证授权逻辑:
- 在测试配置文件中新增Keycloak相关配置:令牌端点、测试用客户端ID、客户端密钥、测试账号用户名密码。
- 测试执行前先向Keycloak申请令牌,请求信息如下:
- 请求地址:
/realms/{你的realm名称}/protocol/openid-connect/token - 请求方法:POST
- 请求体格式:
application/x-www-form-urlencoded - 必填参数:
grant_type=password、client_id=你的客户端ID、client_secret=你的客户端密钥、username=测试用户名、password=测试用户密码
- 请求地址:
- 从返回结果中提取
access_token字段,调用业务接口时添加请求头Authorization: Bearer {提取的access_token}即可。
额外注意事项
- 如果测试用了
@WebMvcTest注解,需要在测试类上添加@Import({WebSecurityConfig.class, 自定义JWT权限转换器类名.class}),确保安全配置和权限转换逻辑生效。 - 如果你的角色校验是直接读取JWT原始字段,需要在模拟JWT时完整填充对应的字段结构,避免校验失败。
内容的提问来源于stack exchange,提问作者neblaz
相关产品推荐
相关产品推荐

