Skip to content

How to handle Microsoft.Data.SqlClient new AccessTokenCallback #33205

@kevinharing

Description

@kevinharing

In version 5.2.0 of Microsoft.Data.SqlClient a new callback was added to the SqlConnection class in order to retrieve an access token. What is the best place to set this property. I don’t think it’s necessary to set it on each execution of the IDbConnection interceptor like I did before with the AccessToken property, right?

More info on the new functionality here.

Previous:

public override async ValueTask<InterceptionResult> ConnectionOpeningAsync(DbConnection connection, ConnectionEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
{
    var sqlConnection = (SqlConnection)connection;
    var accessToken = await _credential.GetTokenAsync(AzureSqlScope, cancellationToken: cancellationToken);

    sqlConnection.AccessToken = accessToken.Token;

    return ValueTask.FromResult(result);
}

New:

private readonly Func<SqlAuthenticationParameters, CancellationToken, Task<SqlAuthenticationToken>> _accessTokenCallback;

public AzureAdAuthenticationDbConnectionInterceptor()
{
    _accessTokenCallback = AccessTokenCallback;
}

public override ValueTask<InterceptionResult> ConnectionOpeningAsync(DbConnection connection, ConnectionEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default)
{
    if (connection is SqlConnection sqlConnection && sqlConnection.AccessTokenCallback is null)
    {
        sqlConnection.AccessTokenCallback = _accessTokenCallback;
    }

    return ValueTask.FromResult(result);
}

private async Task<SqlAuthenticationToken> AccessTokenCallback(SqlAuthenticationParameters sqlAuthenticationParameters, CancellationToken cancellationToken)
{
    var accessToken = await _credential.GetTokenAsync(AzureSqlScope, cancellationToken: cancellationToken);

    return new SqlAuthenticationToken(accessToken.Token, accessToken.ExpiresOn);
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions