如何使用Microsoft Graph for Java缓存令牌



我使用Microsoft Graph SDK处理一些请求,但每次执行GET请求时,它都会执行另一个请求以获取令牌。我试着阅读了有关这方面的文档,但在Java中找不到任何内容。

这是我的客户端的实现

ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(clientId)
.clientSecret(clientSecret)
.tenantId(tenantId)
.httpClient(httpClient)
.build();

我也尝试过在我的生成器中使用方法.tokenCachePersistenceOptions(),但我得到了这个警告/错误

c.m.a.m.CrossProcessCacheFileLock        : null

谢谢!

要实现上述要求首先,您需要对实现MSAL进行身份验证,才能从Azure AD获得令牌

若要获得访问令牌,您的应用程序必须在Microsoft身份平台上注册,并由添加为该应用程序所有者的用户或管理员批准访问所需的Microsoft Graph资源。

有关完整设置,请参阅此MS DOCUMENTMicrosoft Graph的验证和授权基础此示例&GitHub示例|msgraph-sdk-java核心

我一直在寻找同样的想法,下面是我为它实现的:

实现您自己的身份验证提供者类:

public class DelegateAuthenticationProvider implements IAuthenticationProvider {
private String token;
public DelegateAuthenticationProvider(String token) {
this.token = token;
}
@NotNull
@Override
public CompletableFuture<String> getAuthorizationTokenAsync(@NotNull URL url) {
return CompletableFuture.completedFuture(token);
}
}

然后你可以按如下方式使用它:

String token = "<YOUR_TOKEN_STRING>"
IAuthenticationProvider tokenCredentialAuthProvider = new DelegateAuthenticationProvider(token);
// Create the Graph Client with the given Token Provider
GraphServiceClient graphClient = GraphServiceClient.builder()
.authenticationProvider(tokenCredentialAuthProvider)
.buildClient();

如果您收到GraphServiceException代码401,则应续订您的代币。

当您成功使用clientSecretCredential登录时,以下是如何获取令牌:

List<String> scopes = Arrays.asList("https://graph.microsoft.com/.default");
IAuthenticationProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(scopes, clientSecretCredential);
String token = tokenCredentialAuthProvider.getAuthorizationTokenAsync("https://graph.microsoft.com/v1.0/me").get()

希望这能有所帮助。

您可以覆盖为GraphServiceClient 提供的authenticationProvider

import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
import com.microsoft.graph.authentication.TokenCredentialAuthProvider;
import org.jetbrains.annotations.NotNull;
import java.net.URL;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
public class CachingTokenCredentialAuthProvider extends TokenCredentialAuthProvider {
private final TokenCredential tokenCredential;
private final TokenRequestContext context;
private AccessToken accessToken;
public CachingTokenCredentialAuthProvider(@NotNull List<String> scopes, @NotNull TokenCredential tokenCredential) {
super(scopes, tokenCredential);
if (!scopes.isEmpty()) {
this.context = new TokenRequestContext();
this.context.setScopes(scopes);
this.tokenCredential = Objects.requireNonNull(tokenCredential, "tokenCredential parameter cannot be null.");
} else {
throw new IllegalArgumentException("scopes parameter cannot be null or empty");
}
}
@NotNull
@Override
public CompletableFuture<String> getAuthorizationTokenAsync(@NotNull URL requestUrl) {
if (this.shouldAuthenticateRequestWithUrl(Objects.requireNonNull(requestUrl, "requestUrl parameter cannot be null"))) {
if(this.accessToken != null && !OffsetDateTime.now().minusMinutes(1).isAfter(this.accessToken.getExpiresAt())) {
return CompletableFuture.completedFuture(this.accessToken.getToken());
}
return this.tokenCredential.getToken(this.context).toFuture().thenApply(accessToken -> {
saveToken(accessToken);
return accessToken.getToken();
});
} else {
return CompletableFuture.completedFuture(null);
}
}
void saveToken(AccessToken accessToken) {
this.accessToken = accessToken;
}
}

这将缓存令牌,直到它在一分钟后不再有效。

最新更新