我看着MSAL,我正在努力了解在客户端应用中使用它的正确方法。在我的情况下,我想验证用户,然后对“私人”web api应用程序使用id令牌。
现在,我的印象是,如果令牌仍然有效并且请求范围可以得到满足(这是我的解释,这可能是错的)。但是,情况似乎并非如此。我在fiddler看到的是这个方法总是会访问授权端点。
最初,我认为我的客户端服务包装器应始终使用此方法来获取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;
}
GetToken
是一个包装用于验证用户的典型代码的方法(使用try / catch块包装AcquireTokenSilentAsync,当失败时,将用户重定向到AcquireTokenAsync方法以显示登录UI )。
问题:在我的所有后端服务真的要走之前,还有这个额外的电话吗?或者我应该缓存令牌并在所有内部Web服务调用中重复使用它,直到我得到401(然后才应该调用GetToken方法来刷新我的id令牌?)
编辑以提供更多信息
_clientApp = new PublicClientApplication(ClientId,
Authority,
TokenCacheHelper.GetUserCache());
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();
}
}
现在,正在命中令牌缓存助手。我不明白为什么AcquireTokenSilentAsync方法总是调用oauth2端点(https://login.microsoftonline.com/ {azure ad guid} /oauth2/v2.0/token)......
与此同时,我更改了代码,使我的助手类缓存了AuthenticationResult。现在,只有在“内部”应用程序的web api方法之一返回401以响应使用承载授权标头执行的调用时,才会调用AcquireTokenSilentAsync。
答案 0 :(得分:1)
最后,我一直在缓存AuthenticationResult和它的ID令牌。这似乎是最好的选择,因为它为我节省了远程通话。当Web服务返回401时,我只会尝试再次调用AcquireTokenSilentAsync
。