2
votes

I have implemented Azure AD auth following the below sample:

https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect

Here is the code from my application. The users are getting intermittent exception "Failed to acquire token silently. Call method token acquisition". Any help would be highly appreciated.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = ClientId,
            Authority = Authority,

            Notifications = new OpenIdConnectAuthenticationNotifications()
            {
                AuthorizationCodeReceived = (context) =>
                {
                    string userObjectId = null;
                    var code = context.Code;

                    var currentClaimsIdentity = context.AuthenticationTicket.Identity;
                    if (currentClaimsIdentity != null)
                    {
                        userObjectId = currentClaimsIdentity.FindFirst(Constants.ObjectIdentifierClaimType).Value;
                    }

                    ClientCredential credential = new ClientCredential(ClientId, AppKey);
                    AuthenticationContext authContext = new AuthenticationContext(Authority, new SessionCache(userObjectId, HttpContext.Current));
                    authContext.AcquireTokenByAuthorizationCode(code, StandardSettings.ReplyUrl, credential, Constants.GraphResourceBaseUrl);

                    return Task.FromResult(0);
                },

                AuthenticationFailed = context =>
                {
                    context.HandleResponse();
                    context.Response.Redirect("/");

                    return Task.FromResult(0);
                }
            }
        });



/// <summary>
    /// Gets the access token.
    /// </summary>
    /// <returns>The access token for service call.</returns>
    private string GetAccessToken()
    {
        string userName = null;
        AuthenticationResult authenticationResult = null;

        ClaimsPrincipal currentClaimsPrincipal = ClaimsPrincipal.Current;
        if (currentClaimsPrincipal != null)
        {
            userName = currentClaimsPrincipal.FindFirst(ClaimTypes.Name).Value;
        }

        try
        {
            authenticationResult = this.GetAuthenticationResult();

            if (authenticationResult.ExpiresOn < DateTimeOffset.UtcNow)
            {
                Trace.TraceWarning("Access token expired for the user: {0}. Challenge the user authentication to get a new token.", userName);
                this.httpCurrentContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
            }
        }
        catch (AdalSilentTokenAcquisitionException ex)
        {
            Trace.TraceWarning("Failed to acquire the token for the user: {0} with exception: {1}. Challenge the user authentication for retry.", userName, ex);
            this.httpCurrentContext.GetOwinContext().Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }

        if (authenticationResult == null)
        {
            try
            {
                authenticationResult = this.GetAuthenticationResult();
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Failed to acquire the token on the retry for the user: {0} with the exception: {1}.", userName, ex);
                throw new AdalException(
                    AdalError.FailedToAcquireTokenSilently,
                    "The session expired or the token cache was reset. Please sign out and then navigate to the url again to re-authenticate.");
            }
        }

        return authenticationResult.AccessToken;
    }

    /// <summary>
    /// Get the authentication result for the request.
    /// </summary>
    /// <returns>The authentication result.</returns>
    private AuthenticationResult GetAuthenticationResult()
    {
        string userObjectId = null;

        ClaimsPrincipal currentClaimsPrincipal = ClaimsPrincipal.Current;
        if (currentClaimsPrincipal != null)
        {
            userObjectId = currentClaimsPrincipal.FindFirst(Constants.ObjectIdentifierClaimType).Value;
        }

        AuthenticationContext authContext = new AuthenticationContext(
                   Startup.Authority,
                   new SessionCache(userObjectId, this.httpCurrentContext));

        ClientCredential credential = new ClientCredential(Startup.ClientId, Startup.AppKey);
        return authContext.AcquireTokenSilent(
            Constants.GraphResourceBaseUrl,
            credential,
            new UserIdentifier(userObjectId, UserIdentifierType.UniqueId));
    }
1

1 Answers

2
votes

That message appears for a variety of reasons:

  • the cache you are using is empty
  • the cache does not contain a valid refresh token (expired, etc)
  • the cache does not contain a refresh token for the authority/clientid/user combination you specified
  • the identifier for the user does not correspond to the actual user identifier that was originally issued in the token