azureauthenticationazure-identity

AppAuthentication to Azure.Identity Migration


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?


Solution

  • 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;
            }
        }