使用Spring获取Azure AD访问令牌时Authorization code格式错误或无效
解决Azure AD OAuth2获取Access Token时的
invalid_grant错误 从你提供的日志和代码来看,你在调用acquireTokenByAuthorizationCode时遇到了invalid_grant错误,这个错误通常和授权码有效性、回调URI配置或客户端凭据不匹配有关。下面是几个常见的排查和解决方向:
1. 确认授权码的有效性
- 授权码只能使用一次,如果之前已经用该code换取过token,再次调用就会触发此错误。检查是否存在重复调用或调试时重复使用同一code的情况。
- 授权码有有效期(通常为5分钟),若获取code后间隔过久才去换token,code过期也会导致错误。
2. 验证回调URI(currentUri)的一致性
Azure AD要求代码中使用的回调URI,必须和Azure Portal中注册应用时配置的重定向URI完全一致:
- 检查URI的大小写、末尾是否带斜杠(比如
http://localhost:8080/callback和http://localhost:8080/callback/会被视为不同URI) - 本地调试时,确保所用URI和Portal里配置的开发环境URI完全匹配
3. 检查客户端凭据(Client ID和Client Secret)
- 确认代码里的
clientId和clientSecret,和Azure Portal中注册应用的应用程序(客户端)ID、客户端密码完全一致,注意不要有多余空格或拼写错误。 - 如果客户端密码已过期,需在Azure Portal重新生成新密码并更新到代码中。
4. 核对Authority和Resource参数
- 确保
authority格式正确,全球Azure环境下应为https://login.microsoftonline.com/加上你的tenant ID或域名。 - 确认
resource参数是目标资源的正确ID(比如调用Microsoft Graph API时应为https://graph.microsoft.com/),且和Azure AD中配置的权限范围对应。
代码优化建议
可以给代码增加错误日志输出,方便排查具体失败原因:
public AuthenticationResult getAccessToken(AuthorizationCode authorizationCode, String currentUri) throws Throwable { String authCode = authorizationCode.getValue(); ClientCredential credential = new ClientCredential(clientId, clientSecret); AuthenticationContext context = null; AuthenticationResult result = null; ExecutorService service = null; try { service = Executors.newFixedThreadPool(1); context = new AuthenticationContext(authority + tenant + "/", true, service); Future<AuthenticationResult> future = context.acquireTokenByAuthorizationCode( authCode, new URI(currentUri), credential, resource, null ); result = future.get(); } catch (ExecutionException e) { // 新增日志输出错误详情 System.err.println("获取Token失败:" + e.getCause().getMessage()); throw e.getCause(); } catch (URISyntaxException e) { System.err.println("回调URI格式错误:" + e.getMessage()); throw e; } finally { if (service != null) { service.shutdown(); } } return result; }
如果以上排查后仍有问题,建议查看Azure AD的审核日志,里面会有更详细的失败原因描述,帮助你精准定位问题。
内容的提问来源于stack exchange,提问作者20 ans IPl
相关产品推荐
相关产品推荐

