The new Azure.Identity
library seems to be the recommended way for authenticating services within Azure. In particular the DefaultAzureCredentials()
class works seamlessly in local development scenarios and in deployed code without having to make any code changes.
This is easy to use with the newer management SDKs (the ones with names like Azure.ResourceManager...
) because we can just write new DefaultAzureCredentials()
and pass that to the management SDK when creating a new client.
Unfortunately, the older management SDKs (the ones with names like Microsoft.Azure.Management...
) do not integrate with Azure.Identity
"out-of-the-box". They also do not plan to add support for Azure.Identity
to these older APIs because they are instead focusing on porting everything to the newer versions.
However, not every resource in Azure has a new version management API yet and so in some cases you're stuck using the old ones. Fortunately, there is a relatively straight forward way to bridge the gap and still use Azure.Identity
with those older APIs.
There's a GitHub repo which contains an example of how to achieve this. I think it's by one of the developers on the Microsoft team, but isn't officially supported by Microsoft. There is no NuGet package for it and they recommend just copying the bits you need.
I actually found that the code in that sample repo was overly complex for my needs and in my case that all I needed was this. Note, I've copied this from my F# project without testing it, so I might have made a mistake in the conversion to C#, but hopefully it's close enough that you get the idea.
class AzureIdentityFluentCredentialAdapter : AzureCredentials
{
public AzureIdentityFluentCredentialAdapter(string tenantId)
: base(default(DeviceCredentialInformation), tenantId, AzureEnvironment.AzureGlobalCloud)
{
}
public override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var creds = DefaultAzureCredential() // Use the new Azure.Identity library to get access tokens
var accessToken = await creds.GetTokenAsync(
new TokenRequestContent(new [] { "https://management.azure.com/.default" }),
cancellationToken);
return await TokenCredentials(accessToken.Token)
.ProcessHttpRequestAsync(request, cancellationToken);
}
}
This example doesn't do any token caching, but for my purposes I wasn't too bothered about this. It's also hardcoded the scope that I request the token for because I knew I was only going to be using this with the Azure management API.