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

调用Microsoft Graph API返回400错误,Graph Explorer可正常运行求助

调用Microsoft Graph /v1.0/me接口返回400 Bad Request问题

使用Azure Active Directory认证调用Microsoft Graph API的/v1.0/me接口时,返回HTTP 400 Bad Request错误。同一个客户端ID在Graph Explorer中能够成功调用,但本地Java代码始终报错。以下是相关代码及错误信息:

获取令牌代码

IClientCredential credential = ClientCredentialFactory.createFromSecret(CLIENT_SECRET);
ConfidentialClientApplication cca = ConfidentialClientApplication.builder(CLIENT_ID, credential).authority(AUTHORITY).build();
IAuthenticationResult result;
try {
    SilentParameters silentParameters = SilentParameters.builder(Collections.singleton(SCOPE)).build();
    // 尝试静默获取令牌,这里会失败因为缓存中没有对应令牌
    result = cca.acquireTokenSilently(silentParameters).join();
} catch (Exception ex) {
    if (ex.getCause() instanceof MsalException) {
        ClientCredentialParameters parameters = ClientCredentialParameters.builder(Collections.singleton(SCOPE)).build();
        // 获取令牌,成功后会在控制台打印令牌信息
        result = cca.acquireToken(parameters).join();
    } else {
        // 处理其他异常
        throw ex;
    }
}
System.out.println(result.accessToken());

调用Graph API代码

URL url = new URL("https://graph.microsoft.com/v1.0/me");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept","application/json");

int httpResponseCode = conn.getResponseCode();
if(httpResponseCode == HTTPResponse.SC_OK) {

    StringBuilder response;
    try(BufferedReader in = new BufferedReader(
            new InputStreamReader(conn.getInputStream())){

        String inputLine;
        response = new StringBuilder();
        while (( inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
    }
    return response.toString();
} else {
    return String.format("Connection returned HTTP code: %s with message: %s",
            httpResponseCode, conn.getResponseMessage());
}

错误信息:Connection returned HTTP code: 400 with message: Bad Request


问题原因

你当前使用的是客户端凭证流(Client Credential Flow)获取令牌,但/v1.0/me接口的设计是获取当前登录用户的信息,要求令牌必须关联具体用户。而客户端凭证流是服务对服务的认证方式,获取的令牌无用户关联,因此调用/me接口会返回400错误。

Graph Explorer能成功调用,是因为它采用的是授权码流(Authorization Code Flow),会先引导用户登录,获取的令牌绑定了具体用户身份,符合/me接口的调用要求。


解决方案

方案一:切换为授权码流获取用户令牌

如果业务需要访问当前用户的信息,需将认证方式改为授权码流:

  1. 在Azure AD应用注册页面,添加重定向URI(如http://localhost:8080/redirect),并启用"授权码流"。
  2. 修改令牌获取代码示例(Web应用场景):
ConfidentialClientApplication cca = ConfidentialClientApplication.builder(CLIENT_ID, credential)
        .authority(AUTHORITY)
        .build();

Set<String> scopes = new HashSet<>(Arrays.asList("User.Read"));
// authorizationCode是用户登录后回调返回的授权码
AuthorizationCodeParameters parameters = AuthorizationCodeParameters.builder(authorizationCode, new URI(REDIRECT_URI))
        .scopes(scopes)
        .build();

IAuthenticationResult result = cca.acquireToken(parameters).join();

方案二:改用/users/{user-id}接口

如果业务无需关联当前登录用户,仅需获取特定用户信息,可在客户端凭证流基础上,调用/v1.0/users/{user-id}接口,同时确保Azure AD应用已添加对应的应用权限(如User.Read.All)。

修改API调用代码:

// 替换为目标用户的ID或用户主体名称(UPN)
String userId = "target-user@your-domain.com";
URL url = new URL("https://graph.microsoft.com/v1.0/users/" + userId);

内容的提问来源于stack exchange,提问作者elvaone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:46:24