AppAuthentication to Azure.Identity Migration

63 Views Asked by At

I have a code similar to this:

new KeyVaultClient(new TokenCredentials(myBearerToken));

But, I'm migrating from AppAuthentication to Azure.Identity, so I have followed this guide: https://learn.microsoft.com/en-us/dotnet/api/overview/azure/app-auth-migration?view=azure-dotnet. The main problem is that I can not find a way to use Bearer Token, I have tried this:

new SecretClient(new Uri(keyVaultURI), new ClientSecretCredential(tenantId, clientId, myBearerToken));

Is there any way to accomplish this migration with a Bearer Token?

1

There are 1 best solutions below

3
Gaurav Mantri On BEST ANSWER

The way I have solved this problem is by creating a new class that extends TokenCredential class from Azure.Core namespace (ClientSecretCredential also extends the same class) and pass the bearer token in its constructor.

This is how my code looks like:

using System.IdentityModel.Tokens.Jwt;
using Azure.Core;

namespace MyNamespace;

/// <summary>
/// Creates a token credential class using an access token.
/// </summary>
internal sealed class AccessTokenCredential : TokenCredential
{
    /// <summary>
    /// Creates an instance of <see cref="AccessTokenCredential"/>.
    /// </summary>
    /// <param name="accessToken">
    /// JWT encoded access token.
    /// </param>
    public AccessTokenCredential(string accessToken)
    {
        AccessToken = accessToken;
    }
    
    /// <summary>
    /// Gets the access token.
    /// </summary>
    private string AccessToken { get; }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="requestContext"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
    {
        return new ValueTask<AccessToken>(GetAccessToken());
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="requestContext"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
    {
        return GetAccessToken();
    }

    /// <summary>
    /// Validates access token and returns <see cref="AccessToken"/>.
    /// </summary>
    /// <returns>
    /// <see cref="AccessToken"/>.
    /// </returns>
    /// <exception cref="ArgumentException">
    /// Access token is invalid.
    /// </exception>
    private AccessToken GetAccessToken()
    {
        if (Core.Utilities.CoreHelper.TryParseJwtSecurityToken(AccessToken, out JwtSecurityToken token))
        {
            return new AccessToken(AccessToken, token.ValidTo);
        }
        throw new ArgumentException(nameof(AccessToken));
    }
}
    /// <summary>
    /// Tries to create an instance of <see cref="JwtSecurityToken"/> from <paramref name="jwtEncodedString"/>. 
    /// </summary>
    /// <param name="jwtEncodedString">
    /// JWT encoded string.
    /// </param>
    /// <param name="jwtSecurityToken">
    /// <see cref="JwtSecurityToken"/>.
    /// </param>
    /// <returns>
    /// True if a JWT security token can be created using input string otherwise false.
    /// </returns>
    public static bool TryParseJwtSecurityToken(string jwtEncodedString, out JwtSecurityToken jwtSecurityToken)
    {
        try
        {
            jwtSecurityToken = new JwtSecurityToken(jwtEncodedString);
            return true;
        }
        catch (ArgumentNullException)
        {
            jwtSecurityToken = null;
            return false;
        }
        catch (ArgumentException)
        {
            jwtSecurityToken = null;
            return false;
        }
    }