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

调用acquireTokenByAuthorizationCode获取令牌时执行异常求助

问题描述

已将Microsoft的Partner-Center-Java-Samples中secure-app-model/keyvault下的partnerconsent项目克隆到本地Eclipse环境。确认authorization code、redirectUrl、clientId及clientSecret参数均正确传入,但执行future.get()时触发Execution异常,相关代码及堆栈信息如下:

获取AccessToken的方法代码

private AuthenticationResult getAccessToken(HttpServletRequest request, AuthorizationCode code)
    throws Throwable
{
    AuthenticationContext authContext; 
    AuthenticationResult authResult;
    ExecutorService service = null;
    Future<AuthenticationResult> future;

    try
    {
        service =  Executors.newFixedThreadPool(1);

        authContext = new AuthenticationContext(
            MessageFormat.format("{0}/common", authority), 
            true, 
            service);

        future = authContext.acquireTokenByAuthorizationCode(
            code.getValue(),
            new URI(redirectUrl),
            new ClientCredential(
                clientId,
                clientSecret), 
            null); 

        authResult = future.get();
    }
    catch(ExecutionException ex)
    {
        throw ex.getCause();
    }
    ...

    return authResult;
}

acquireTokenByAuthorizationCode方法定义(来自com.microsoft.aad.adal4j包)

public Future<AuthenticationResult> acquireTokenByAuthorizationCode(
        final String authorizationCode, final URI redirectUri,
        final ClientCredential credential,
        final AuthenticationCallback callback) {
    this.validateAuthCodeRequestInput(authorizationCode, redirectUri,
            credential, null);
    return this.acquireTokenByAuthorizationCode(authorizationCode,
            redirectUri, credential, null, callback);
}

异常堆栈信息

java.lang.ClassCastException: class java.util.Collections$SingletonList cannot be cast to class java.lang.String (java.util.Collections$SingletonList and java.lang.String are in module java.base of loader 'bootstrap')
    at com.nimbusds.oauth2.sdk.util.URLUtils.serializeParameters(URLUtils.java:103)
    at com.microsoft.aad.adal4j.AdalTokenRequest.toOAuthRequest(AdalTokenRequest.java:160)
    at com.microsoft.aad.adal4j.AdalTokenRequest.executeOAuthRequestAndProcessResponse(AdalTokenRequest.java:86)
    at com.microsoft.aad.adal4j.AuthenticationContext.acquireTokenCommon(AuthenticationContext.java:930)
    at com.microsoft.aad.adal4j.AcquireTokenCallable.execute(AcquireTokenCallable.java:70)
    at com.microsoft.aad.adal4j.AcquireTokenCallable.execute(AcquireTokenCallable.java:38)
    at com.microsoft.aad.adal4j.AdalCallable.call(AdalCallable.java:47)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)
根因分析

这个ClassCastException的核心原因是依赖版本冲突:

  • adal4j(Microsoft Azure AD认证库)依赖特定版本的nimbus-oauth2-sdk处理OAuth2请求序列化。
  • 项目中引入了与adal4j不兼容的nimbus-oauth2-sdk版本,导致URLUtils.serializeParameters方法中,原本期望的String类型参数被传入List(具体是Collections$SingletonList),触发类型转换异常。
  • 常见场景是高版本nimbus库修改了参数返回类型,但旧版adal4j仍按String类型处理,反之亦然。
解决方案
  1. 排查依赖冲突
    使用构建工具的依赖树命令查看nimbus-oauth2-sdk的版本:

    • Maven:执行mvn dependency:tree
    • Gradle:执行./gradlew dependencies
      找出所有引入该依赖的模块,确认是否存在多版本冲突。
  2. 强制使用兼容版本
    根据你使用的adal4j版本,锁定对应的nimbus-oauth2-sdk版本:

    • 例如,adal4j 1.6.0需搭配nimbus-oauth2-sdk 6.2.3;adal4j 1.9.0适配nimbus-oauth2-sdk 9.8.1(具体可查看adal4j官方pom文件)。
    • Maven示例配置(排除冲突依赖+显式声明兼容版本):
      <!-- 显式声明兼容的nimbus版本 -->
      <dependency>
          <groupId>com.nimbusds</groupId>
          <artifactId>oauth2-oidc-sdk</artifactId>
          <version>6.2.3</version>
      </dependency>
      
      <!-- 给adal4j排除自带的nimbus依赖,避免冲突 -->
      <dependency>
          <groupId>com.microsoft.azure</groupId>
          <artifactId>adal4j</artifactId>
          <version>1.6.0</version>
          <exclusions>
              <exclusion>
                  <groupId>com.nimbusds</groupId>
                  <artifactId>oauth2-oidc-sdk</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      
  3. 清理并重建项目

    • 在Eclipse中,右键项目 -> Maven -> Update Project(勾选Force Update of Snapshots/Releases)
    • 清理编译目录(如target文件夹),重新执行构建命令。

内容的提问来源于stack exchange,提问作者ab.it.gcp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:45:39