DEV Community

kosmos
kosmos

Posted on

Handle authentication when using Azure SDKs in .NET (C#)

When using official Azure SDKs in .NET (C#), you typically create a client first and pass the Credential to it. This time, I want to tweak that part a bit.


A common approach is to use ApiKeyCredential, where you pass the API key string. For example, something like the following.

var client = new AzureOpenAIClient( new Uri(openai_endpoint), new ApiKeyCredential(key) ); 
Enter fullscreen mode Exit fullscreen mode

In Azure-related scenarios, when using Managed Identities or relying on local Azure CLI authentication information, you typically use DefaultAzureCredential as shown below.

var client = new AzureOpenAIClient( new Uri(openai_endpoint), new DefaultAzureCredential() ); 
Enter fullscreen mode Exit fullscreen mode

This time, it's about how to handle situations when those scenarios don't fit. Here is a concrete example. Suppose you are using Azure OpenAI Service and aggregating API entry points with Azure API Management (APIM). Also, access from APIM to Azure OpenAI Service itself uses Managed Identities.
In this situation, when a user (client app) accesses APIM, you want to use a JWT access token obtained by the app to verify and determine access permission in APIM.
Inside the app, regardless of OpenAI, there might be an access token that allows access to, for example, an internal API server, and you want to use that to call Azure OpenAI managed by APIM. (Let's ignore the idea of handling this with Azure OpenAI's IAM for now. It can be troublesome if the account tenant and resource tenant differ, and you don't want to mess with IAM for just ordinary usage without privileges.)

So, what should you do when you already have an access token? The conclusion is that you can create and implement a custom TokenCredential by inheriting from Azure.Core.TokenCredential.

public class CustomCredential : Azure.Core.TokenCredential { public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) { return new AccessToken("your custom token", DateTimeOffset.UtcNow.AddHours(1)); } public override async ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) { return new AccessToken("your custom token", DateTimeOffset.UtcNow.AddHours(1)); } } 
Enter fullscreen mode Exit fullscreen mode

You just create a class like that and pass it instead of other Credentials.

var client = new AzureOpenAIClient( new Uri(openai_endpoint), new CustomCredential() ); 
Enter fullscreen mode Exit fullscreen mode

After that, GetToken()/GetTokenAsync() will be called when necessary, so it's fine to appropriately provide the access token or similar. If you also pass the RefreshOn argument, it should handle the update process (including re-calls) as needed.

Basically, it is less troublesome to use derived classes of TokenCredential provided by the SDK or DefaultAzureCredential, but this is another possible approach. As a side note, since DefaultAzureCredential chains credentials, if the operating environment is fixed, such as deploying on Azure in a Release build, it is more efficient to pass ManagedIdentityCredential or fix it without chaining, as this reduces overhead.

Top comments (0)