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
相关产品推荐
相关产品推荐

