Azure - AD - AcquireTokenSilent giving error failed_to_acquire_token_silently

倾然丶 夕夏残阳落幕 提交于 2019-12-04 15:37:09

We were able to resolve this. It seems to be a small mistake in the code itself. When the AccessToken expires, it throws an exception and it tries to fetch a new one using AcquireTokenByRefreshToken in the catch block. Here we were not setting the newly received refresh token back in the Cookie. We need to add below statement in the catch block also, so that it would get the Refresh token, which can then be passed back to generate a new Access Token.

httpCookie.Value = authenticationResult.RefreshToken;

First of all, before using AcquireTokenSilent you must invoke AcquireTokenByAuthorizationCodeAsync.

var context = new AuthenticationContext(authorityUri);
var credential = new ClientCredential(clientId, clientSecretKey);

await context.AcquireTokenByAuthorizationCodeAsync(authorizationCode, new Uri(redirectUri), credential);

AcquireTokenByAuthorizationCodeAsync stores access token and refresh token in TokenCache.DefaultShared (for user uniqueId received from auth procedure).

Assuming you do that, access tokens and refresh tokens do expire. If that happens, you must catch AdalSilentTokenAcquisitionException exception:

try
{
    // currentUser = new UserIdentifier() for: ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")
    AuthenticationResult authResult = await context.AcquireTokenSilentAsync(resourceUri, credential, currentUser);

    return authResult.AccessToken;
}
catch (AdalSilentTokenAcquisitionException)
{
    return null;
}

Invoke this method before every request to the resource. It doesn't cost much, ideally nothing, or oauth API hit with refreshToken.

But when AdalSilentTokenAcquisitionException is thrown (or it's a first call). You must call procedure that performs full access code retrieval from oauth API. What procedure? It depends on the type of auth process you're using.

With full owin auth it can be:

  • redirect to authority uri with {"response_type", "code" }
  • or invoking HttpContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType); (return null from controller's action as the Challenge() method alters HTTP response to force redirection to auth server). End processing of current request (with returning null). Auth server will invoke your authorization method (AuthorizationCodeReceived event from UseOpenIdConnectAuthentication's Notifications) with new authorization code. Later, redirect back to the origin page that needs the token.

So, you may get AdalSilentTokenAcquisitionException because cache is expired and refreshToken is expired. You have to reauthenticate again (it's transparent, no login page required).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!