使用Java HttpClient通过客户端凭证模式获取戴尔API访问令牌报错400如何解决
问题根源
你代码的核心错误是参数位置写错了:
- 你把
grant_type=client_credentials放在了请求头中,但OAuth2客户端模式的授权要求这个参数必须放在application/x-www-form-urlencoded格式的POST请求体里,而不是请求头 - 你用
BodyPublishers.noBody()发送了空请求体,导致服务端检测不到必填的grant_type参数,返回参数缺失的400错误
修正后的代码
import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpClient.Redirect; import java.net.http.HttpClient.Version; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.time.Duration; import java.util.Base64; public class Main { public static void main(String[] args) throws IOException, InterruptedException { String tokenURL = "https://apigtwb2c.us.dell.com/auth/oauth/v2/token"; String clientID = "{redacted}"; String clientSecret = "{redacted}"; String formatted = clientID + ":" + clientSecret; String encoded = Base64.getEncoder().encodeToString((formatted).getBytes()); HttpClient client = HttpClient.newBuilder() .version(Version.HTTP_1_1) .followRedirects(Redirect.NORMAL) .connectTimeout(Duration.ofSeconds(10)) .build(); // 构造表单格式的请求体,放入grant_type参数 String formBody = "grant_type=client_credentials"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(tokenURL)) .headers("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8", "Accept", "application/json", "Authorization", "Basic " + encoded) // 发送带参数的请求体,而不是空体 .POST(BodyPublishers.ofString(formBody)) .build(); System.out.println(request.headers()); HttpResponse<String> response = client.send(request, BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); } }
改动说明
- 移除了请求头中的
grant_type参数 - 构造了表单格式的请求体字符串,替换原来的空请求体发送
- 原有Basic认证的逻辑无需调整,和curl的
-u参数逻辑完全一致
内容的提问来源于stack exchange,提问作者seraphina
相关产品推荐
相关产品推荐

