简体   繁体   English

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

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

I'm building a multi-user, multi-tenant app that will access the Microsoft Graph API on behalf of many users while they're offline.我正在构建一个多用户、多租户应用程序,它将在离线时代表许多用户访问 Microsoft Graph API。

Because the app uses the Microsoft Identity for external OIDC authentication, during the user's first login, I already requested the appropriate scopes/consents and received the access/refresh tokens issued by Microsoft.因为该应用程序使用 Microsoft Identity 进行外部 OIDC 身份验证,所以在用户首次登录期间,我已经请求了适当的范围/同意,并收到了 Microsoft 颁发的访问/刷新令牌。 The tokens are saved in the database.令牌保存在数据库中。

Now I want to use Microsoft.Graph which makes accessing the Graph API much easier, but it seems that a big part of this SDK was written to retrieve tokens, which I do not need because I already have the tokens.现在我想使用Microsoft.Graph这使得访问 Graph API 变得更加容易,但似乎这个 SDK 的很大一部分是为了检索令牌而编写的,我不需要它,因为我已经有了令牌。

I do, however, want the SDK client to automatically use the stored refresh token to obtain new access tokens, instead of having to manually handle the refreshing logic myself, if possible.但是,我确实希望 SDK 客户端自动使用存储的刷新令牌来获取新的访问令牌,而不必自己手动处理刷新逻辑,如果可能的话。

Upon research, I found that I can pass in an null for the AuthenticationProvider when constructing the GraphServiceClient , and manually attach bearer token to the client like this:经过研究,我发现我可以在构造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();

This does work and bypasses the client's token retrieval logic, but the problem now is that it won't handle access token expiration/renewal.这确实有效并绕过了客户端的令牌检索逻辑,但现在的问题是它不会处理访问令牌到期/更新。 So I have to use separate code to make sure I always pass in a non-expired access token, and renew the token myself using the refresh token if necessary.因此,我必须使用单独的代码来确保始终传递未过期的访问令牌,并在必要时使用刷新令牌自己更新令牌。

I wonder if there is a way to customize GraphServiceClient such that it doesn't try to obtain tokens using separate OAuth2/OIDC flows, but instead knows how to find an existing refresh token stored in my database, and use that refresh token to manage its renewal/expiration logic like it does for tokents it receives with its regular flows.我想知道是否有一种方法可以自定义GraphServiceClient ,这样它就不会尝试使用单独的 OAuth2/OIDC 流来获取令牌,而是知道如何找到存储在我的数据库中的现有刷新令牌,并使用该刷新令牌来管理它更新/到期逻辑,就像它通过常规流程接收的令牌一样。

The ideal flow works like this:理想的流程是这样的:

  1. Pass in a parameter (the user's ID in my database) to create a GraphServiceClient .传入一个参数(我的数据库中的用户 ID)来创建一个GraphServiceClient

  2. The client uses this UserID to lookup the stored tokens in my database (EF Core).客户端使用此用户 ID 在我的数据库 (EF Core) 中查找存储的令牌。

  3. If the stored access token already expired, use the stored refresh token to get a new one, and update the tokens in the database.如果存储的访问令牌已过期,请使用存储的刷新令牌获取新令牌,并更新数据库中的令牌。

Would this be possible with the SDK? SDK 可以做到这一点吗?

Your advice will be greatly appreciated.您的建议将不胜感激。

You can implement the IAuthenticationProvider interface in your own custom class, then do the necessary token checking/refresh in the AuthenticateRequestAsync function.您可以在自己的自定义 class 中实现IAuthenticationProvider接口,然后在AuthenticateRequestAsync function 中进行必要的令牌检查/刷新。 See https://github.com/microsoftgraph/msgraph-training-dotnet-core/blob/main/demo/GraphTutorial/Authentication/DeviceCodeAuthProvider.cs for an example.有关示例,请参阅https://github.com/microsoftgraph/msgraph-training-dotnet-core/blob/main/demo/GraphTutorial/Authentication/DeviceCodeAuthProvider.cs

I'd recommend looking at the MSAL library to handle all of the token logic for you.我建议查看MSAL 库来为您处理所有令牌逻辑。 You can hook into it's token cache to serialize it how you want (to store it in your database, for example).您可以挂钩到它的令牌缓存以按照您的意愿对其进行序列化(例如,将其存储在数据库中)。 In the example I linked I'm using MSAL, and you can see I don't have to do any checking for expired tokens, it's all handled for me.在我链接的示例中,我使用的是 MSAL,您可以看到我不必对过期令牌进行任何检查,这一切都已为我处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM