MSAL:AcquireTokenSilentAsync 始终与端点交互

MSAL: AcquireTokenSilentAsync always interacts with the endpoint

我正在查看 MSAL,并试图了解在客户端应用程序中使用它的正确方法是什么。就我而言,我想对用户进行身份验证,然后针对 "private" 网络 api 应用程序使用 id 令牌。

现在,我的印象是,如果令牌仍然有效并且可以满足请求范围(这是我的解释,可能是错误的)。然而,情况似乎并非如此。我在 fiddler 中看到的是,此方法将始终访问授权端点。

最初,我认为我的客户端服务包装器应该始终调用此方法以获得 id 令牌,然后通过身份验证承载将其传递到后端网站 header。这是我的意思的一个例子:

public async Task<string> GetAllWorkers() {
    _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await GetToken());

    var request = new HttpRequestMessage(HttpMethod.Get, _url);
    var resposta = await _httpClient.SendAsync(request);
    var content = await resposta.Content.ReadAsStringAsync();
    return content;
}

GetToken 是一种包装用于验证用户身份的典型代码的方法(使用 try/catch 块包装 AcquireTokenSilentAsync,当失败时,将用户重定向到 AcquireTokenAsync 方法显示登录 UI).

问题:在我的所有后端服务之前进行这个额外调用是否真的可行?或者我应该缓存令牌并在所有内部 Web 服务调用中重复使用它直到我收到 401(然后我才应该调用 GetToken 方法来刷新我的 ID 令牌?)

正在编辑以提供更多信息

_clientApp = new PublicClientApplication(ClientId, 
                                       Authority, 
                                       TokenCacheHelper.GetUserCache());

TokenCacheHelper 是大多数 Azure AD 示例附带的令牌缓存助手。 return 验证 header 的 GetToken 方法是与封装上面所示的 _clientApp 字段的帮助程序交互的单个衬里:

return (await _helper.AuthenticateUser()).IdToken

这是 AuthenticateUser 方法:

public async Task<AuthenticationResult> AuthenticateUser() {
    try {
        return await _clientApp.AcquireTokenSilentAsync(_scopes, _clientApp.Users.FirstOrDefault());
    }
    catch (MsalUiRequiredException ex) {
        return await RetryWithGraphicalUI();
    }
}

现在,正在命中令牌缓存助手。我不明白的是为什么 AcquireTokenSilentAsync 方法最终总是调用 oauth2 端点 (https://login.microsoftonline.com/{azure ad guid}/oauth2/v2.0/token)...

与此同时,我更改了让我的助手 class 缓存 AuthenticationResult 的代码。现在,AcquireTokenSilentAsync 只会在 "internal" 应用程序的一种 Web api 方法 return 401 响应使用不记名授权 header.[=17= 执行的调用时调用]

最后,我缓存了 AuthenticationResult 及其 ID 令牌。这似乎是最好的选择,因为它为我节省了远程调用。我只会在网络服务 returns 401.

时再次尝试调用 AcquireTokenSilentAsync