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

Java SpringBoot从Azure AD获取Access Token报错求助

问题分析与解决方案

错误原因

你当前使用的是授权码(Authorization Code)模式,但该模式需要先通过授权页面获取有效的code参数,你直接把授权端点URL(authUrl)当作code传入,完全不符合模式要求,导致Azure AD返回invalid_grant错误。

另外,你的需求是无弹窗直接传入凭据,授权码模式本身需要用户交互,不适合你的场景,应该改用资源所有者密码凭据(ROPC)模式,该模式允许直接在代码中传入用户名和密码获取令牌。

修正后的代码

使用ROPC模式重新实现,代码如下:

import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class AzureADTokenFetcher {
    public static void main(String[] args) {
        String clientId = "c64a70a8-7794-44a6-a9b8-4f44f09e17ee";
        String clientSecret = "-DW8Q~JwYM611PR7EchiCU~HKLLqjv1ogLHvAc8O";
        String accessTokenUrl = "https://login.windows.net/f761680c-0582-4825-b245-62c1d05b6b3a/oauth2/token?resource=https://api.businesscentral.dynamics.com";
        // 替换为你的服务账号用户名和密码
        String username = "your-service-account-username@your-domain.com";
        String password = "your-service-account-password";

        String encodedValue = getBase64Encoded(clientId, clientSecret);

        OAuthClient client = new OAuthClient(new URLConnectionClient());
        try {
            OAuthClientRequest request = OAuthClientRequest.tokenLocation(accessTokenUrl)
                    .setGrantType(GrantType.PASSWORD) // 指定ROPC授权模式
                    .setClientId(clientId)
                    .setClientSecret(clientSecret)
                    .setUsername(username)
                    .setPassword(password)
                    .setScope("Financials.ReadWrite.All user_impersonation")
                    .buildBodyMessage();

            request.addHeader("Authorization", "Basic " + encodedValue);

            OAuthJSONAccessTokenResponse token = client.accessToken(request, OAuth.HttpMethod.POST, OAuthJSONAccessTokenResponse.class);
            String finalToken = token.getAccessToken();

            System.out.println("Access Token: " + finalToken);
            // 后续可直接用该令牌调用Azure服务接口,获取数据并更新数据库

        } catch (OAuthSystemException | OAuthProblemException e) {
            e.printStackTrace();
        }
    }

    public static String getBase64Encoded(String id, String password) {
        return Base64.getEncoder().encodeToString((id + ":" + password).getBytes(StandardCharsets.UTF_8));
    }
}

关键注意事项

  • ROPC模式限制:仅支持未启用多因素认证(MFA)的账号,若服务账号开启了MFA,需改用客户端凭据(Client Credentials)模式(无需用户账号,直接用ClientId和ClientSecret获取令牌,适合纯服务间调用场景)。
  • 权限配置:确保Azure AD应用注册中已添加Financials.ReadWrite.All等所需API权限,并完成管理员同意授权。
  • 端点优化:当前使用的login.windows.net是旧版Azure AD端点,推荐迁移到新版login.microsoftonline.com,功能一致且更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:35:21