我们希望使用AcquireTokenAsync代表用户使用以下语法获取令牌
public static async Task<UserTokenCache> GetAccessTokens(string userUniqueId)
{
UserTokenCache cache = null;
AuthenticationContext authContext = null;
ClientCredential credential = new ClientCredential(clientId, appKey);
AuthenticationResult powerBIResult = null;
AuthenticationResult graphResult = null;
bool isAdalException = false;
try
{
authContext = new AuthenticationContext(Startup.Authority, new NaiveSessionCache(userUniqueId));
powerBIResult = await authContext.AcquireTokenSilentAsync(pbiResourceID, credential, new UserIdentifier(userUniqueId, UserIdentifierType.UniqueId));
graphResult = await authContext.AcquireTokenSilentAsync(graphResourceId, credential, new UserIdentifier(userUniqueId, UserIdentifierType.UniqueId));
cache = new UserTokenCache
{
GraphAccessToken = graphResult.AccessToken,
PBIAccessToken = powerBIResult.AccessToken,
PBITokenExpires = powerBIResult.ExpiresOn,
GraphTokenExpires = graphResult.ExpiresOn
};
}
catch (JsonException je)
{
ExceptionLogger.LogInApplicationInsight(je);
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties(),
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
catch (AdalException ae)
{
ExceptionLogger.LogInApplicationInsight(ae);
if (ae.ErrorCode == "failed_to_acquire_token_silently")
{
isAdalException = true;
}
else
{
HttpContext.Current.GetOwinContext().Authentication.Challenge(
new AuthenticationProperties(),
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
catch (Exception ex)
{
ExceptionLogger.LogInApplicationInsight(ex);
}
if(isAdalException)
{
try
{
string cacheValue = Convert.ToString(cacheManager.get(userUniqueId));
string decryptedCache = CryptographyUtility.Decrypt(cacheValue);
cache = JsonConvert.DeserializeObject<UserTokenCache>(decryptedCache);
UserAssertion pbiAssertion = new UserAssertion(cache.PBIAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", UserProperties.UserName);
UserAssertion graphAssertion = new UserAssertion(cache.GraphAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", UserProperties.UserName);
cache = null;
powerBIResult = await authContext.AcquireTokenAsync(pbiResourceID, credential, pbiAssertion);
graphResult = await authContext.AcquireTokenAsync(graphResourceId, credential, graphAssertion);
cache = new UserTokenCache
{
GraphAccessToken = graphResult.AccessToken,
PBIAccessToken = powerBIResult.AccessToken,
PBITokenExpires = powerBIResult.ExpiresOn,
GraphTokenExpires = graphResult.ExpiresOn
};
} catch (Exception ex)
{
ExceptionLogger.LogInApplicationInsight(ex);
}
}
return cache;
}
如果我们使用cache.PBIAccessToken和cache.GraphAccessToken来计算在AcquireTokenAsync方法中使用的用户断言,则抛出TenantId不匹配的错误。在这种情况下,需要使用什么令牌来计算UserAssertion。
答案 0 :(得分:0)
通常,我们通常使用AcquireTokenAsync来获取访问令牌并在用户首次登录时刷新令牌。之后,您可以静默获取令牌(调用AcquireTokenSilentAsync以获取accessToken),它将从TokenCache获取令牌或静默使用refreshToken。如果访问令牌和刷新令牌都已过期,您可能会收到AdalSilentTokenAcquisitionException(无法以静默方式获取令牌。调用方法AcquireToken)。
然后您可以捕获该异常,并调用HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" },OpenIdConnectAuthenticationDefaults.AuthenticationType);
将用户重定向到azure广告登录页面,登录后,用户使用AcquireTokenSilentAsync调用api将起作用,因为访问令牌/刷新令牌存在于缓存中,并且未过期。如果我正确理解您的要求,if(isAdalException)
中的代码将毫无用处。