当我已经将用户的刷新令牌存储在数据库中时,使用 Microsoft.Graph SDK 的最佳方式?

Best way to use Microsoft.Graph SDK when I already have users' refresh tokens stored in database?

我正在构建一个多用户、多租户的应用程序,它将代表许多离线用户访问 Microsoft Graph API。

由于应用程序使用Microsoft Identity 进行外部OIDC 身份验证,在用户首次登录时,我已经请求了相应的scopes/consents 并收到了Microsoft 颁发的access/refresh 令牌。令牌保存在数据库中。

现在我想使用 Microsoft.Graph 这使得访问图形 API 变得容易得多,但似乎这个 SDK 的很大一部分是为了检索令牌而编写的,我不需要它,因为我已经有代币了。

但是,我希望 SDK 客户端自动使用存储的刷新令牌来获取新的访问令牌,而不是必须自己手动处理刷新逻辑(如果可能的话)。

经过研究,我发现我可以在构造GraphServiceClient时为AuthenticationProvider传入一个null,然后像这样手动将不记名令牌附加到客户端:

var graphClient = new GraphServiceClient(authenticationProvider: null);

var requestHeaders = new List<HeaderOption>() 
                  { new HeaderOption("Authorization", "Bearer " + myToken) };

var me = await graphClient.Me.Request(requestHeaders).GetAsync();

这确实有效并绕过了客户端的令牌检索逻辑,但现在的问题是它不会处理访问令牌expiration/renewal。所以我必须使用单独的代码来确保我始终传入未过期的访问令牌,并在必要时使用刷新令牌自己更新令牌。

我想知道是否有一种方法可以自定义 GraphServiceClient,这样它就不会尝试使用单独的 OAuth2/OIDC 流程获取令牌,而是知道如何找到存储在中的现有刷新令牌我的数据库,并使用该刷新令牌来管理其 renewal/expiration 逻辑,就像它对其通过常规流接收的令牌所做的那样。

理想的流程是这样的:

  1. 传入一个参数(我数据库中的用户ID)创建一个GraphServiceClient.

  2. 客户端使用此用户 ID 查找我的数据库 (EF Core) 中存储的令牌。

  3. 如果存储的访问令牌已经过期,使用存储的刷新令牌获取新的,并更新数据库中的令牌。

SDK 可以吗?

非常感谢您的建议。

您可以在自己的自定义class中实现IAuthenticationProvider接口,然后在AuthenticateRequestAsync函数中做必要的标记checking/refresh。有关示例,请参阅 https://github.com/microsoftgraph/msgraph-training-dotnet-core/blob/main/demo/GraphTutorial/Authentication/DeviceCodeAuthProvider.cs

我建议查看 MSAL library 来为您处理所有令牌逻辑。您可以连接到它的令牌缓存以按照您想要的方式对其进行序列化(例如,将其存储在您的数据库中)。在我链接的示例中,我使用的是 MSAL,您可以看到我不需要对过期令牌进行任何检查,一切都已为我处理。