Xamarin MSAL 何时调用 AcquireTokenSilent
Xamarin MSAL When to call AcquireTokenSilent
MSAL 示例展示了如何登录、获取访问令牌以及使用该令牌调用 API。它没有显示的是如何调用第 2、第 3 等 API 调用。您是否应该缓存您的访问令牌并将其用于每个 API 调用直到它过期或在进行每个 API 调用之前调用 AquireTokenSilent
? MSAL 没有 return 刷新令牌,所以我无法自己刷新它。我将访问令牌配置为在一小时后过期。如果用户使用该应用程序超过一个小时,我认为我需要刷新令牌。
我尝试在每次 API 调用之前调用它,但它很慢,而且看起来每次都获得一个新令牌。它可能需要 200 到 800 毫秒的任何时间。我还为 HttpClient
创建了一个 DelegatingHandler
,它查找 401 响应并调用 AcquireTokenSilent
来刷新令牌。问题是当我从 DelegatingHandler
中进行此调用时应用程序挂起。调用从不 returns.
编辑:我为此在 Github 中提交了一个错误,因为 MSAL 应该 return 缓存的令牌,而不是每次都刷新令牌。这没有发生,因为我使用的是 user_impersonate
范围。 Microsoft 对此进行了错误修复。同时,如果您遇到此问题并且错误修复尚未发布,请删除 user_impersonate
范围,它应该可以正常工作。我已经删除了我自己用来缓存令牌的代码。
原文:
我解决了这个问题。我相信正确的路径是缓存令牌并将其用于后续调用。使用 DelegatingHandler
观察 401 响应,然后调用 AcquireTokenSilent
即可。我有一个导致应用程序挂起的错误。这似乎是个好方法。
即使您已经弄清楚问题出在哪里,我还是想确保您遵循的是正确的模式。
以下代码来自此link (link):
private async Task InitializeGraphClientAsync()
{
var currentAccounts = await PCA.GetAccountsAsync();
try
{
if (currentAccounts.Count() > 0)
{
// Initialize Graph client
GraphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async (requestMessage) =>
{
var result = await PCA.AcquireTokenSilent(Scopes, currentAccounts.FirstOrDefault())
.ExecuteAsync();
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", result.AccessToken);
}));
await GetUserInfo();
IsSignedIn = true;
}
else
{
IsSignedIn = false;
}
}
catch(Exception ex)
{
Debug.WriteLine(
$"Failed to initialized graph client. Accounts in the msal cache: {currentAccounts.Count()}. See exception message for details: {ex.Message}");
}
}
重要的部分是他们创建新的 Graph 客户端时。他们向 aqcuire 添加了一个将随每个请求一起执行的委托,并向请求添加了一个令牌 header。如果令牌即将过期,那么此 AcquireTokenSilent
方法将首先使用 Refresh token
获取新令牌,然后将其返回给此方法。
如果您使用自己的 API 并且还需要此令牌,您可以使用相同的逻辑创建自己的委托。对于每个请求,您执行 method/delegate 将(缓存的或新的)令牌添加到您的请求中。
不要自己存储令牌,Microsoft 库就是为此而创建的,并以安全的方式存储它们。
MSAL 示例展示了如何登录、获取访问令牌以及使用该令牌调用 API。它没有显示的是如何调用第 2、第 3 等 API 调用。您是否应该缓存您的访问令牌并将其用于每个 API 调用直到它过期或在进行每个 API 调用之前调用 AquireTokenSilent
? MSAL 没有 return 刷新令牌,所以我无法自己刷新它。我将访问令牌配置为在一小时后过期。如果用户使用该应用程序超过一个小时,我认为我需要刷新令牌。
我尝试在每次 API 调用之前调用它,但它很慢,而且看起来每次都获得一个新令牌。它可能需要 200 到 800 毫秒的任何时间。我还为 HttpClient
创建了一个 DelegatingHandler
,它查找 401 响应并调用 AcquireTokenSilent
来刷新令牌。问题是当我从 DelegatingHandler
中进行此调用时应用程序挂起。调用从不 returns.
编辑:我为此在 Github 中提交了一个错误,因为 MSAL 应该 return 缓存的令牌,而不是每次都刷新令牌。这没有发生,因为我使用的是 user_impersonate
范围。 Microsoft 对此进行了错误修复。同时,如果您遇到此问题并且错误修复尚未发布,请删除 user_impersonate
范围,它应该可以正常工作。我已经删除了我自己用来缓存令牌的代码。
原文:
我解决了这个问题。我相信正确的路径是缓存令牌并将其用于后续调用。使用 DelegatingHandler
观察 401 响应,然后调用 AcquireTokenSilent
即可。我有一个导致应用程序挂起的错误。这似乎是个好方法。
即使您已经弄清楚问题出在哪里,我还是想确保您遵循的是正确的模式。
以下代码来自此link (link):
private async Task InitializeGraphClientAsync()
{
var currentAccounts = await PCA.GetAccountsAsync();
try
{
if (currentAccounts.Count() > 0)
{
// Initialize Graph client
GraphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async (requestMessage) =>
{
var result = await PCA.AcquireTokenSilent(Scopes, currentAccounts.FirstOrDefault())
.ExecuteAsync();
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", result.AccessToken);
}));
await GetUserInfo();
IsSignedIn = true;
}
else
{
IsSignedIn = false;
}
}
catch(Exception ex)
{
Debug.WriteLine(
$"Failed to initialized graph client. Accounts in the msal cache: {currentAccounts.Count()}. See exception message for details: {ex.Message}");
}
}
重要的部分是他们创建新的 Graph 客户端时。他们向 aqcuire 添加了一个将随每个请求一起执行的委托,并向请求添加了一个令牌 header。如果令牌即将过期,那么此 AcquireTokenSilent
方法将首先使用 Refresh token
获取新令牌,然后将其返回给此方法。
如果您使用自己的 API 并且还需要此令牌,您可以使用相同的逻辑创建自己的委托。对于每个请求,您执行 method/delegate 将(缓存的或新的)令牌添加到您的请求中。
不要自己存储令牌,Microsoft 库就是为此而创建的,并以安全的方式存储它们。