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