question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Synchronous retrieving of access token when using Azure.Identity leads to performance issues

See original GitHub issue

Requirements We have the requirement to provide a constantly fast Web Api with response times of less than 50ms. The Web Api provides data from Azure Sql.

Current Solution We use Managed Identity to authorize access from an Azure App Service to Azure Sql. In order to have an authorized SqlConnection for EF Core we use our own DbConnectionInterceptor.

public class AADTokenInjectorDbInterceptor : DbConnectionInterceptor
{
    private readonly IAzureCredentialProviderFactory _azureCredentialProviderFactory;
    private readonly IMeasureTime _measureTime;
    private static readonly string[] Scopes = { "https://database.windows.net/.default" };
    private AccessToken _accessToken;

    public AADTokenInjectorDbInterceptor(IMeasureTime measureTime)
    {
        _measureTime = measureTime;
    }

    public override async Task<InterceptionResult> ConnectionOpeningAsync(
        DbConnection connection,
        ConnectionEventData eventData,
        InterceptionResult result,
        CancellationToken cancellationToken = default)
    {
        var sqlConnection = (SqlConnection)connection;

        await RefreshTokenIfNecessary();
        sqlConnection.AccessToken = _accessToken.Token;
        return result;
    }

    private async Task RefreshTokenIfNecessary()
    {
        if (_accessToken.ExpiresOn != default && DateTimeOffset.UtcNow < _accessToken.ExpiresOn)
            return;

        _accessToken = await _measureTime.For("Refresh token for SQL Server",
            async () =>
            {
                var tokenCredential = new ChainedTokenCredential(new AzureCliCredential(), new ManagedIdentityCredential());
                return await tokenCredential.GetTokenAsync(new TokenRequestContext(Scopes), CancellationToken.None);
            });
    }
}

Issue The “synchronous” retrieving of an access token, which can take several seconds, slows down requests constantly. e.g. Sql query (5ms) + retrieving access token (1500ms) = 1505ms instead of 5ms.

Failed Solution Idea We tried to cache the access token using ASP.NET Core Background Service in order to remove the blocking/synchronous call from our own DbConnectionInterceptor implementation. This idea back fired as we assumed TokenCredential.GetTokenAsync would give us a new access token which it doesn’t.

Questions Is there anyway on how we can force Azure.Identity to give us a new access token? Are there any other solutions to achieve a constantly fast responding Web Api that access Sql Server using Managed Identity?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:14 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
bbieniekcommented, May 12, 2022

Hi,

Can this be reopened? We are also seeing occasional slow requests to the database when the managed identity is used. We don’t use any interceptor and I am guessing this is happening because sometimes obtaining the token is slow. image

1reaction
schaabscommented, Jan 22, 2021

@Rookian Thanks for reaching out to us with this issue, and I’m sorry your having this trouble.

Is there anyway on how we can force Azure.Identity to give us a new access token?

Azure.Identity doesn’t provide an mechanism to force issuing a new token because there is no way for the library to guarantee this as the token can be cached at many levels, including the STS. So any mechanism we would add to enable this would only be a best attempt, and unreliable.

Also I would second what @jongio suggested about reordering your credentials putting the ManagedIdentityCredential before the AzureCliCredential, I think that the long delays you’re seeing in acquiring a token (> 1sec) are probably due to the the AzureCliCredential. This credential shells out the to the Azure CLI to obtain a token and the CLI startup can easily take as long as the delays your seeing. Could you try switching the ordering of your credentials and see if you’re still seeing the same latency when deployed to a host with managed identity enabled?

If this still doesn’t fix the problem, I think your background refresh approach could also be a viable work around, but since you cannot guarantee you’ll get a new token when calling GetTokenAsync I would suggest simply doing this refresh more frequently.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Azure AD authentication & authorization error codes
Learn about the AADSTS error codes that are returned from the Azure AD security token service (STS).
Read more >
Troubleshoot Pass-through Authentication - Azure
This article helps you find troubleshooting information about common issues regarding Azure AD Pass-through Authentication. Important.
Read more >
Troubleshoot Azure Files identity-based authentication and ...
This article lists common problems when using SMB Azure file shares with identity-based authentication. It also provides possible causes and ...
Read more >
Troubleshoot Azure AD connectivity issues
First, make sure that machine. config is correctly configured and that the Microsoft Azure AD Sync service has been restarted once after the ......
Read more >
Troubleshooting Microsoft Defender for Identity known issues
Describes how you can troubleshoot issues in Microsoft Defender for Identity.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found