调用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类型处理,反之亦然。
解决方案
排查依赖冲突
使用构建工具的依赖树命令查看nimbus-oauth2-sdk的版本:- Maven:执行
mvn dependency:tree - Gradle:执行
./gradlew dependencies
找出所有引入该依赖的模块,确认是否存在多版本冲突。
- Maven:执行
强制使用兼容版本
根据你使用的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>
- 例如,adal4j 1.6.0需搭配
清理并重建项目
- 在Eclipse中,右键项目 -> Maven -> Update Project(勾选Force Update of Snapshots/Releases)
- 清理编译目录(如target文件夹),重新执行构建命令。
内容的提问来源于stack exchange,提问作者ab.it.gcp
相关产品推荐
相关产品推荐

