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

如何使用msal4j与Azure Blob Storage库实现访问令牌更新

我们使用微软的Java库访问Azure Blob Storage,通过msal4j库采用OAuth2客户端访问模式获取访问令牌,代码片段如下:

StorageCredentialsToken storageCredentialsToken = new StorageCredentialsToken(account_name, generateOAuthToken());
storageAccount = new CloudStorageAccount(storageCredentialsToken, true);

private String generateOAuthToken() throws MalformedURLException {
  String authority = String.format(ACTIVE_DIRECTORY_ENDPOINT + "/%s/oauth2/v2.0/token", tenant_id);
  Set<String> scope = Collections.singleton(String.format("https://%s.blob.core.windows.net/.default", account_name));
  IClientCredential credential = ClientCredentialFactory.createFromSecret(client_secret);
  ConfidentialClientApplication cca = ConfidentialClientApplication
      .builder(client_id, credential)
      .authority(authority)
      .build();
  ClientCredentialParameters parameters = ClientCredentialParameters
      .builder(scope)
      .build();
  IAuthenticationResult result = cca.acquireToken(parameters).join();
  return result.accessToken();
}

上述代码可正常运行,但访问令牌最终会过期,此时相关操作会开始报错。理论上存在刷新令牌可用于更新访问令牌,但刷新令牌似乎未被包含在IAuthenticationResult接口中。我的疑问如下:

  • 采用当前模式能否实现令牌更新?
  • 如果不行,有什么解决方案?是否存在其他支持令牌更新的模式?还是应该忽略更新逻辑,直接重新获取全新的访问令牌?
  • 如果获取了新的访问令牌,如何将其配置到已有的storageAccount客户端中?如果保留了StorageCredentialsToken实例,是否可以直接调用StorageCredentialsToken.updateToken()完成更新?

更新:收到的回复很有帮助,但最终我发现在使用clientId/tenantId的场景下无法实现真正的令牌更新,这可能是设计使然?不过在令牌过期前重新获取新令牌的方案是可行的,代码片段如下:

IAuthenticationResult authResult = generateOAuthToken();
StorageCredentialsToken storageCredentialsToken = new StorageCredentialsToken(account_name, authResult.accessToken());
new Thread(new OAuthTokenRenewer(authResult, storageCredentialsToken)).start();
storageAccount = new CloudStorageAccount(storageCredentialsToken, true);

private IAuthenticationResult generateOAuthToken() throws MalformedURLException {
  String authority = String.format(ACTIVE_DIRECTORY_ENDPOINT + "/%s/oauth2/v2.0/token", tenant_id);
  Set<String> scope = Collections.singleton(String.format("https://%s.blob.core.windows.net/.default", account_name));
  IClientCredential credential = ClientCredentialFactory.createFromSecret(client_secret);
  ConfidentialClientApplication cca = ConfidentialClientApplication
      .builder(client_id, credential)
      .authority(authority)
      .build();
  ClientCredentialParameters parameters = ClientCredentialParameters
      .builder(scope)
      .build();
  return cca.acquireToken(parameters).join();
}


private class OAuthTokenRenewer implements Runnable {
  IAuthenticationResult authResult;
  final StorageCredentialsToken storageCredentialsToken;
  public OAuthTokenRenewer(IAuthenticationResult authResult, StorageCredentialsToken storageCredentialsToken) {
    this.authResult = authResult;
    this.storageCredentialsToken = storageCredentialsToken;
  }
  @Override
  public void run() {
    while (true) {
      try {
        Thread.sleep(60 * 1000L);
        long now = System.currentTimeMillis();
        if (authResult.expiresOnDate().getTime() - now < RENEWAL_WINDOW_MS) {
          authResult = generateOAuthToken();
          storageCredentialsToken.updateToken(authResult.accessToken());
        }
      } catch (Exception ex) {
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者Wheezil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:30:02