Authentication MSAL:AcquireTokenSilentAsync始终与端点交互

Authentication MSAL:AcquireTokenSilentAsync始终与端点交互,authentication,asp.net-web-api,azure-active-directory,msal,Authentication,Asp.net Web Api,Azure Active Directory,Msal,我正在关注MSAL,我正在试图了解在客户端应用程序中使用它的正确方式。在我的例子中,我希望对用户进行身份验证,然后对“私有”web api应用程序使用id令牌 现在,我的印象是AcquireTokenSilentAsync将重用缓存中的现有令牌(如果可用),而不执行对身份验证端点的额外调用,前提是该令牌仍然有效,并且可以满足请求者的范围(这是我的解释,可能是错误的)。然而,情况似乎并非如此。我在fiddler中看到的是,该方法将始终访问授权端点 最初,我认为我的客户机服务包装器应该始终使用此方法

我正在关注MSAL,我正在试图了解在客户端应用程序中使用它的正确方式。在我的例子中,我希望对用户进行身份验证,然后对“私有”web api应用程序使用id令牌

现在,我的印象是AcquireTokenSilentAsync将重用缓存中的现有令牌(如果可用),而不执行对身份验证端点的额外调用,前提是该令牌仍然有效,并且可以满足请求者的范围(这是我的解释,可能是错误的)。然而,情况似乎并非如此。我在fiddler中看到的是,该方法将始终访问授权端点

最初,我认为我的客户机服务包装器应该始终使用此方法来获取id令牌,然后通过身份验证承载头将id令牌传递到后端网站。这里有一个例子来说明我的意思:

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;
}
TokenCacheHelper是大多数Azure AD示例附带的令牌缓存帮助器。返回身份验证头的
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();
    }
}
公共异步任务{azure ad guid}/oauth2/v2.0/token)


同时,我更改了代码,使助手类缓存AuthenticationResult。现在,AcquireTokenSilentAsync将仅在“内部”应用程序的web api方法之一返回401以响应使用承载授权标头执行的调用时被调用。

最后,我对AuthenticationResult及其ID令牌进行了缓存。这似乎是最好的选择,因为它节省了我的远程通话。只有当web服务返回401时,我才会再次尝试调用
AcquireTokenSilentAsync

您能告诉我们有关您初始化应用程序的权限的更多信息吗?我们想知道为什么缓存没有被命中。你好,Jean Marc。缓存被命中,因为UI未显示,但acquiretokensilentasync将始终调用授权端点以获取令牌。你想让我展示更多的代码吗?只是PublicClientApplication的构造函数(我假设这是一个公共客户端应用程序)。你到达公共端点了吗?您是否使用MSA(Microsoft个人帐户)身份?还是AAD?我已经尝试添加有关此问题的更多信息…@LuisAbreu您是否尝试将令牌缓存序列化到会话或内存,例如,请参阅
public async Task<AuthenticationResult> AuthenticateUser() {
    try {
        return await _clientApp.AcquireTokenSilentAsync(_scopes, _clientApp.Users.FirstOrDefault());
    }
    catch (MsalUiRequiredException ex) {
        return await RetryWithGraphicalUI();
    }
}