Spring Boot JWT接口测试遇403错误问题求助
解决方案
核心问题
测试返回403的根本原因是默认securityEnabled为true,此时所有业务API都要求已认证。你Mock的JwtAuthenticationToken要么没被Spring Security的OAuth2资源服务器逻辑认可,要么因为自定义CustomAuthentication包装导致身份校验失败。
具体修复方案
方案1:测试时直接关闭安全校验(最快捷)
单元测试不需要验证全局安全逻辑,直接通过配置关闭:
在测试类上添加注解:
@TestPropertySource(properties = "conf.security.enabled=false")
或者在application-test.yml中配置:
conf: security: enabled: false
方案2:正确Mock JWT认证(保留安全校验逻辑)
如果要测试认证流程,需要让Spring Security认可你的Mock对象:
- 删掉
CustomAuthentication包装:直接用JwtAuthenticationToken作为principal传入,自定义包装没必要还容易出兼容问题。 - Mock RBAC接口的返回:
CustomAuthoritiesConverter会调用rbacProxy获取角色权限,必须Mock这部分逻辑,否则会因为调用真实服务失败导致权限为空。 - 给Mock JWT添加必要的Claim:确保JWT包含
GlobalConstants.DEFAULT_CLAIM,因为转换器会从这个Claim取用户名。
修改后的测试代码示例:
@MockBean private InnerRbacProxy rbacProxy; @Test void Should_Add_Person() throws Exception { // given var person = DataGenerator.person(); var memberType = AccidentMemberEnum.INSURED; List<GrantedAuthority> updatedAuthorities = new ArrayList<>(); updatedAuthorities.add(new SimpleGrantedAuthority(RoleTypeEnum.Fields.ROLE_AxaClaimsRoleDirector)); // Mock RBAC返回 when(rbacProxy.getRolesByUsername(anyString(), anyString())) .thenReturn(Collections.singletonList(new RoleDto(RoleTypeEnum.Fields.ROLE_AxaClaimsRoleDirector))); when(rbacProxy.getUserPermissions(anyString(), anyString(), anyString())) .thenReturn(Collections.emptyList()); // 构造带必要Claim的Mock JWT Jwt mockJwt = mock(Jwt.class); when(mockJwt.getClaimAsString(GlobalConstants.DEFAULT_CLAIM)).thenReturn(username); var jwtAuthenticationToken = new JwtAuthenticationToken(mockJwt, updatedAuthorities, username); jwtAuthenticationToken.setDetails(Collections.singletonMap(GlobalConstants.AS400_USER_CLAIM, username)); jwtAuthenticationToken.setAuthenticated(true); // when when(claimService.addPerson(username, PREDECLARATION_NUMBER, person, memberType, false)) .thenReturn(DataGenerator.personCreationCaseOK()); // then var json = ow.writeValueAsString(person); mockMvc.perform(MockMvcRequestBuilders.post(BASE_URL + PREDECLARATION_NUMBER + "/peoples?memberType=INSURED") .principal(jwtAuthenticationToken) .contentType(MediaType.APPLICATION_JSON) .content(json)) .andExpect(status().isOk()); }
方案3:修复安全配置中的冗余代码
你的SecurityConfig里重复调用了.cors().and().cors(),这会导致CORS过滤器重复注册,可能引发异常,删掉重复的.cors().and()即可:
@Override public void configure(HttpSecurity http) throws Exception { // @formatter:off http.cors() .and() .csrf().disable() //NOSONAR .exceptionHandling() .accessDeniedHandler(securityAccessDeniedHandler()) .authenticationEntryPoint(securityAuthEntryPoint()); // 后续逻辑不变... }
内容的提问来源于stack exchange,提问作者Oussama Abouzid
相关产品推荐
相关产品推荐

