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

Spring Boot测试中使用Okta获取Access Token遇400错误求助

Okta认证测试代码400错误排查(Spring Boot)

问题背景

前端React已通过OktaSignInWidget实现Okta认证,后端Spring Boot需借助Okta生成的Access Token测试所有API。编写了如下测试方法,但请求返回400 Bad Request,寻求代码审查:

@Test
public void testOktaAuthorization() {
    String tokenEndpoint = "https://dev-10835870.okta.com/api/v1/authn";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    Map<String, Object> requestBody = new HashMap<>();
    requestBody.put("client_id", clientId);
    requestBody.put("username",email);
    requestBody.put("password",password);

    HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);


    ResponseEntity<Map> responseEntity = new RestTemplate().postForEntity(tokenEndpoint, requestEntity, Map.class);

    sessionToken = (String) responseEntity.getBody().get("sessionToken");

    final String authorizeEndpoint = domain + "/oauth2/default/v1/authorize";
    final UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(authorizeEndpoint)
            .queryParam("response_type", "token")
            .queryParam("scope", "openid")
            .queryParam("state", "TEST")
            .queryParam("nonce", "TEST")
            .queryParam("client_id", clientId)
            .queryParam("redirect_uri", redirectUri)
            .queryParam("sessionToken", sessionToken);

    final HttpHeaders headers1 = new HttpHeaders();
    headers1.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

    final HttpEntity<String> request = new HttpEntity<>("", headers1);

    final ResponseEntity<String> response = new RestTemplate().exchange(builder.build().toUri(),HttpMethod.GET, request, String.class);
    System.out.println(response);

}

问题分析与修复建议

1. 认证端点参数错误

/api/v1/authn是Okta的基础认证端点,用于生成sessionToken,这个端点不需要传递client_id——该参数属于OAuth2专属参数。移除请求体中的client_id:

// 删除此行
// requestBody.put("client_id", clientId);

2. 隐式流的使用限制

你用response_type=token发起的是OAuth2隐式流,Okta要求这种流必须通过浏览器跳转完成(依赖前端会话或用户交互),后端直接用RestTemplate发起GET请求会被判定为非法请求,返回400。

同时,GET请求无需设置APPLICATION_FORM_URLENCODED类型的请求头,这个头是POST表单请求专用的,直接去掉相关配置。

3. 后端获取Token的正确方式

后端测试API应使用**密码模式(Resource Owner Password Credentials Flow)**直接获取Access Token,这是后端服务获取令牌的标准方式。修改后的代码示例:

@Test
public void testOktaAuthorization() {
    // 替换为Okta OAuth2令牌端点
    String tokenEndpoint = "https://dev-10835870.okta.com/oauth2/default/v1/token";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    
    // 添加Basic Auth:client_id与client_secret拼接后Base64编码
    String authStr = clientId + ":" + clientSecret;
    String base64Auth = Base64.getEncoder().encodeToString(authStr.getBytes());
    headers.set("Authorization", "Basic " + base64Auth);

    MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
    requestBody.add("grant_type", "password");
    requestBody.add("username", email);
    requestBody.add("password", password);
    requestBody.add("scope", "openid"); // 可根据需求添加其他权限,如api://default/access_as_user

    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(requestBody, headers);

    ResponseEntity<Map> tokenResponse = new RestTemplate().postForEntity(tokenEndpoint, requestEntity, Map.class);
    System.out.println("Token响应: " + tokenResponse.getBody());
    
    // 提取Access Token
    String accessToken = (String) tokenResponse.getBody().get("access_token");
    
    // 使用Access Token测试目标API
    HttpHeaders apiHeaders = new HttpHeaders();
    apiHeaders.set("Authorization", "Bearer " + accessToken);
    HttpEntity<Void> apiRequest = new HttpEntity<>(apiHeaders);
    ResponseEntity<String> apiResponse = new RestTemplate().exchange("你的API地址", HttpMethod.GET, apiRequest, String.class);
    System.out.println("API响应: " + apiResponse.getBody());
}

4. 额外配置检查

  • 确保Okta应用已启用密码模式:在Okta控制台的应用设置中,找到「Allowed grant types」并勾选「Password」。
  • 避免硬编码敏感信息(client_id、client_secret、用户密码),建议通过配置文件或环境变量注入。

内容的提问来源于stack exchange,提问作者kakarot-757

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:25:32