如何使用AuthorizationCodeCredential与GraphServiceClient实现多请求及自动续期?
问题解决方案
核心原因
你遇到的问题本质是AuthorizationCodeCredential默认没有持久化令牌缓存,且授权码只能使用一次。首次请求时,凭证会用授权码换取访问令牌和刷新令牌,但这些令牌仅存在内存中;后续请求若重新创建AuthorizationCodeCredential实例,因授权码已失效,就会触发"No access token found"错误。
解决步骤
1. 启用令牌持久化缓存
Azure Identity库支持配置令牌缓存的持久化方式,通过TokenCachePersistenceOptions指定缓存存储位置(如用户会话、加密数据库等),确保令牌在请求之间保留。
2. 复用GraphServiceClient实例
不要在每次请求时重新创建GraphServiceClient和AuthorizationCodeCredential,应将这些实例与用户会话绑定,每个用户对应唯一实例,后续请求直接复用已有的令牌缓存。
3. 自动刷新令牌的实现
只要凭证实例被复用且缓存中有有效刷新令牌,AuthorizationCodeCredential会自动在访问令牌过期时,用刷新令牌换取新的访问令牌,无需手动干预。
修改后的代码示例
// 在用户登录回调(获取授权码后)执行 final String clientId = "YOUR_CLIENT_ID"; final String tenantId = "YOUR_TENANT_ID"; final String clientSecret = "YOUR_CLIENT_SECRET"; final String authorizationCode = "AUTH_CODE_FROM_REDIRECT"; final String redirectUrl = "YOUR_REDIRECT_URI"; final List<String> scopes = Arrays.asList("User.Read"); final String userId = "当前用户唯一标识"; // 比如登录后的用户ID // 配置令牌缓存,用用户ID区分不同缓存实例 TokenCachePersistenceOptions cacheOptions = new TokenCachePersistenceOptions() .setName("user-token-cache-" + userId); final AuthorizationCodeCredential credential = new AuthorizationCodeCredentialBuilder() .clientId(clientId) .tenantId(tenantId) .clientSecret(clientSecret) .authorizationCode(authorizationCode) .redirectUrl(redirectUrl) .tokenCachePersistenceOptions(cacheOptions) // 绑定缓存配置 .build(); final TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider(scopes, credential); final GraphServiceClient<Request> graphClient = GraphServiceClient.builder() .authenticationProvider(authProvider) .buildClient(); // 将graphClient存入用户HttpSession,供后续请求复用 request.getSession().setAttribute("graphClient", graphClient);
后续请求复用实例
// 在后续接口请求中,从会话取出已创建的GraphServiceClient GraphServiceClient<Request> graphClient = (GraphServiceClient<Request>) request.getSession().getAttribute("graphClient"); // 直接调用API,凭证会自动处理令牌过期刷新 User currentUser = graphClient.me().buildRequest().get();
注意事项
- 授权码仅能使用一次,必须在首次获取后立即用于创建凭证,后续不可重复使用同一授权码。
- 若使用会话存储缓存,需合理设置会话过期时间,避免用户操作中途令牌失效。
- 生产环境建议采用加密数据库存储令牌缓存,比会话存储更安全,防止令牌泄露。
内容的提问来源于stack exchange,提问作者Xiaokang Zhang
相关产品推荐
相关产品推荐

