简体   繁体   中英

MSAL System.InvalidOperationException: CompactToken parsing failed with error code: 80049217

I'm using MSAL for .NET to acquire tokens for my Graph API requests, but out of sudden, I'm getting following error, which I can see a lot of post about, but no solution of reason why Error 80049217 happens? Does anyone know why this error occurs and maybe a solution to avoid the error?

System.InvalidOperationException: CompactToken parsing failed with error code: 80049217

UPDATE 22-01-10 Example of method to acquire access token (Client is instance of HttpClient reused by all threads using the factory class containing this method. _confidentialClient is an instance of IConfidentialClientApplication in the MSAL .NET library):

// Multiple threads will access this method
private async Task GetAccessToken()
{
    try
    {
        Console.WriteLine("Acquire token....");
        // Is the .AcquireTokenForClient method thread safe??
        var result = await _confidentialClient.AcquireTokenForClient("https://graph.microsoft.com/.default").ExecuteAsync();
        if(Client.DefaultRequestHeaders.Authorization?.Parameter == result.AccessToken)
        {
            Console.WriteLine("Token havn't changed.");
            return;
        }
        Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
        Console.WriteLine("Acquire token successfully!");
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

All threads interacting with Graph API by this factory class will start by calling the GetAccessToken method to make sure the HttpClient has a valid AccessToken in the Authorization header. As far as I have read about IConfidentialClientApplication, the AcquireTokenForClient() will look for valid tokens in the internal cache, and if there isn't any, acquiring a new one, which is why the method is always invoked by any thread.

It seemed that you wrote this code in your asp.net core backend project, and you wanna a method to help generate access token for different scopes without entering user name/password to sign in, so that it can serve different scenario. But you made a mistake here.

See this document first. In a server/daemon application, you can only use client credential flow to generate access token, so the scope for graph api should be https://graph.microsoft.com/.default , and this section provides the sample code to use client credential flow in your asp.net core app. Here's the snippet.

var scopes = new[] { "https://graph.microsoft.com/.default" };

// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Values from app registration
var clientId = "YOUR_CLIENT_ID";
var clientSecret = "YOUR_CLIENT_SECRET";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM