AcquireTokenSilent always Failed to acquire token

2019-02-12 05:00发布

问题:

Using ADAL I have two AuthenticationContext using a Token Cache persisted in SQL.

Using AcquireTokenByAuthorizationCode it writes the Token in database, but when using AcquireTokenSilent I always get

Failed to acquire token silently. Call method AcquireToken

Here are the details for replication the issue:

I create a Context

AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));

Then I AcquireToken By Authorization

authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential);

At this point, it saves an entry in the database

Then if I call this I get an exception.

authContext.AcquireTokenSilent(_authority, _clientCredential, new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)).AccessToken;

I also tried with the same result:

authContext.AcquireTokenSilent(_authority, _clientId).AccessToken;
authContext.AcquireTokenSilent(_authority, _clientCredential, UserIdentifier.AnyUser).AccessToken;

I Post my AzureAdalCache implementation in this Gist.

Each entry of the Cache is like this.

What Am I missing?

Update

Based on answer of comments of @vibronet I have this

AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential, _eWSResource);
string result = authContext.AcquireTokenSilent(_eWSResource, _clientId, UserIdentifier.AnyUser).AccessToken;

回答1:

The issue was that basically I was using Common Authority https://login.windows.net/common/oauth2/authorize in my App. It works for AcquireTokenByAuthorizationCode() but not for AcquireTokenSilent().

So I needed it to save the TenantId when call AcquireTokenByAuthorizationCode() and an authority use an authority like https://login.windows.net/<tenant ID>/oauth2/authorizewhen call AcquireTokenSilent(). This way the same code above works.



回答2:

I don't understand the call:

authContext.AcquireTokenSilent(
    _authority,
    _clientCredential,
    new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)
).AccessToken;

The UserIdentifier must match the value in the cache, and CompanyID does not sound like any of the identifier you get back for the token.

Please take a look at the sample I pointed you to on the other thread, and specifically on the identifier used in call to AcquireTokenSilent in https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blob/master/TodoListWebApp/Controllers/TodoListController.cs

You don't get to choose which identifier to use in that call, that is determined by what claims AAD issues. The only identifiers you can choose are at the cache instance level, not in individual AcquireToken* calls.



回答3:

Check if token is existing in cache else sign out and ask user to sign in.

AuthenticationContext authContext = new AuthenticationContext(Startup.Authority,
                        new NaiveSessionCache(userObjectID));
                    if (authContext.TokenCache.Count == 0)
                    {
                        authContext.TokenCache.Clear();
                        CosmosInterface.Utils.AuthenticationHelper.token = null;
                        HttpContext.GetOwinContext().Authentication.SignOut(
                            OpenIdConnectAuthenticationDefaults.AuthenticationType,
                            CookieAuthenticationDefaults.AuthenticationType);
                    }


回答4:

I had the same issue in ASPNetCore (1.0) and the reason was that I wasn't storing the authentication token after logging in. I solved it by adding OnAuthorizationCodeReceived in the Startup class and changing my Response ype to ResponseType = OpenIdConnectResponseType.CodeIdToken.

Hope it helps.

Sample: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/blob/aspnet10/WebApp-WebAPI-OpenIdConnect-DotNet/Startup.cs#L100



回答5:

This is an old question - but for me, I needed to clear my cookies on the client and then it forced the browser to re-auth and everything was fine again.