Warm tip: This article is reproduced from stackoverflow.com, please click
asp.net-mvc asp.net-web-api azure azure-active-directory azure-cloud-services

No cache tokens were found during token acquisition

发布于 2020-04-10 10:20:11

I want to send a request from a Controller of the ASP.NET MVC application that is deployed on the Microsoft Azure Cloud Active Directory and receive a response from the service that is still deployed on the Microsoft Azure Cloud Active Directory.

For this purpose, I downloaded an example you can see from here and customize it for myself. A detailed document of my actions is contained in the same link.

When I tested service and web applications on my azure portal, I encountered an error message in the header:

Failed to acquire token silently as no token was found in the cache. Call method AcquireToken

Where the error occurred is the following part in my controller:

            ClientCredential credential = new ClientCredential( clientId, appKey );
            result = await authContext.AcquireTokenSilentAsync( todoListResourceId, credential, new UserIdentifier( userObjectID, UserIdentifierType.UniqueId ) );

clientId: Identifier of my web application installed on Azure AD (For example: c95d45dd-ba7f-41be-a995-1db604afff32)

appKey: Hidden key value of my web application in the portal

todoListResourceId: Identification of my API application installed on Azure AD (For example: 4cfebcb4-6f2e-4eeb-84f2-4220f65774ed)

userObjectID: Value returned from the following piece of code

            string userObjectID = ClaimsPrincipal.Current.FindFirst( "http://schemas.microsoft.com/identity/claims/objectidentifier" ).Value;

i.e. a value for the user who is online in the browser. As stated in the document on my GitHub link, this value is not my Microsoft account that I used when logging into my azure portal, but a value for my user that I registered to my Azure Active Directory

A similar topic to this topic has been discussed and answered here before, but this answer has not solved my problem.

I've been working for days, but I haven't gotten a response from the GET, POST, PUT, DELETE methods in the service. I keep dealing with the error in the title. I'm waiting for your help.

Questioner
Gbsibascin
Viewed
88
Frank Hu MSFT 2020-02-04 07:50

The reason you're receiving this error is because the call acquiretokensilentasync is EXPECTED to throw that error when the cache is empty. This call is meant to be caught in a try catch. If it does throw this error it should call the acquiretokenasync call.

In addition to that it looks like you're trying to utilize the client credential flow with the acquiretokensilentasync call, which is not the right method to use per the ADAL wiki docs.

See here on how to do this properly: https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Client-credential-flows

It looks like you're using an app id and secret, the method in particular on how to do this per the doc linked above is :

AuthenticationContext authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/<tenantId>");
AuthenticationResult result = await authenticationContext.AcquireTokenAsync("https://resourceUrl", clientCredential);

More documentation specifically for the acquiretokensilentasync call can be found here : https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/AcquireTokenSilentAsync-using-a-cached-token

From the doc above :

Recommended pattern to acquire a token

Now that you have seen both AcquireTokenAsync, AcquireTokenSilentAsync, it's the right moment to present the recommended usage pattern for calling these methods. The idea is that you want to minimize the number of signings for the user, and therefore you'd want to:

first try to acquire a token silently, and if this call fails you try to get one interactively. Note that, AcquireTokenSilent does not need to be called in the Client credentials flow (when the application acquires token without a user, but in its own name)

Note that AcquireTokenSilent can fail for several reasons, such as the cache does not contain a token for the user, or the token has expired and cannot be refreshed. For these reasons, a call to AcquireTokenAsync will usually get a token. But there are also issues such as network problems, STS unavailability, etc., which won't be directly solvable. You will see them in more details in the article about best practices for Handling errors.

In addition to that, it looks like you're using the ADAL Library, I suggest to move over to the MSAL library since Microsoft is slowly moving towards utilizing the MSAL libraries and will at some point in the future (maybe far future) move off of ADAL/V1.0 endpoint. There are no current hard dates for this however. The doc on moving over from ADAL to MSAL can be found here :

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Adal-to-Msal