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

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对象:

  1. 删掉CustomAuthentication包装:直接用JwtAuthenticationToken作为principal传入,自定义包装没必要还容易出兼容问题。
  2. Mock RBAC接口的返回:CustomAuthoritiesConverter会调用rbacProxy获取角色权限,必须Mock这部分逻辑,否则会因为调用真实服务失败导致权限为空。
  3. 给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:47:07