Azure Identity 301 - ChainedTokenCredential

Azure Identity is an Azure SDK library that abstracts all the authentication complexities so you can get back to building your Azure solutions.
In Azure Identity 101, we learned about DefaultAzureCredential, which allows you to quickly add authentication to your application with a single line of code:
var client = new SecretClient(vaultUri, new DefaultAzureCredential());
```text
In [Azure Identity 201](/azure-identity-201), we learned about `DefaultAzureCredentialOptions`, which allows you to configure various `DefaultAzureCredential` options. For example if you want to set the user-assigned Managed Identity client Id you would do the following:
```csharp
var client = new SecretClient(vaultUri, new DefaultAzureCredential( new DefaultAzureCredentialOptions { ManagedIdentityClientId = clientId } ));
```csharp
In [Azure Identity 202](/azure-identity-202), we learned about all of the Environment Variables that Azure Identity inspects, which you can override at the system or terminal level. This is convenient when you need to change a setting in an environment without changing code.
In this [Azure Identity 301](/azure-identity-301) post we’ll take a look at using individual credential types, `EnvironmentCredential` and `ChainedTokenCredential` - which allows you to create your own chain of credentials to suit your application needs.
## Individual Credential Types
Up until this point, we’ve been using `DefaultAzureCredential` which is an opinionated and heavily customer-researched chain of credential types. Refer to [Azure Identity 101](/azure-identity-101) for the full list of credential types it attempts to get a token from.
`DefaultAzureCredential` is amazingly useful for getting started quickly. Just new-it-up and go. But, let’s say that you are 100% sure your application will only ever use the Azure CLI to authenticate users, which could happen if it is an internal-developer centric tool. If that is the case, then you could simply new up an `AzureCliCredential` object and use that just like you used `DefaultAzureCredential`.
Here’s what that would look like:
```csharp
var client = new SecretClient(vaultUri, new AzureCliCredential());
```csharp
The benefit of using a discreet credential type is that Azure libraries will only attempt to get a token from that one type and you know where your token is coming from. The downside is that your application will fail if it is unable to get a token from that type.
You can find the full list of credential types here: [Azure.Identity Namespace](https://docs.microsoft.com/en-us/dotnet/api/azure.identity).
## Environment Credential
`EnvironmentCredential` is also a chain of credentials, that includes credentials that authenticate via service principal, app or user. They include `ClientSecretCredential`, `UsernamePasswordCredential`, and `ClientCertificateCredential`. It is include as the first credential type in `DefaultAzureCredential`, but you can also use it directly:
```csharp
var client = new SecretClient(vaultUri, new EnvironmentCredential());
```typescript
You’d use this type directly if you know your app will only ever authenticate with one of those types and you’d like to take advantage of Azure Identity’s built in support for well known Environment Variables.
You can learn more about all of the supported Environment Variables here: [Azure Identity 202](/azure-identity-202)
## Chained Token Credential
`ChainedTokenCredential` is a type that allows you to easily build your own chain of credentials. For example, let’s say that you are 100% sure you want to use Azure CLI for local development and Managed Identity for your production cloud environment. You **could** use `DefaultAzureCredential` for this scenario, because that chain includes both `ManagedIdentityCredential` and `AzureCLiCredential`. It will attempt to get tokens in that order and short-circuit when it gets a token, so in a production environment the `AzureCliCredential` won’t even be executed.
But if you use `DefaultAzureCredential` in this scenario, then there’s a little bit of unknown in exactly how much time it takes to go attempt the credentials that are in the chain that you know you’ll never use. For example, if you know you won’t ever need to try `AzurePowerShellCredential`, then you could exclude it with this:
```csharp
var client = new SecretClient(vaultUri, new DefaultAzureCredential( new DefaultAzureCredentialOptions { ExcludeAzurePowerShellCredential = true } ));
```text
But let’s say you want to also not include the `VisualStudioCodeCredential`, that would look like this:
```csharp
var client = new SecretClient(vaultUri, new DefaultAzureCredential( new DefaultAzureCredentialOptions { ExcludeAzurePowerShellCredential = true, ExcludeVisualStudioCodeCredential = true } ));
```sql
You’d get to a point where you have so many `Exclude...Credential` statements that `DefaultAzureCredential` starts to gets cumbersome.
This is where `ChainedTokenCredential` come into the picture.
When…
1. You know the exact list of credentials you want your application to attempt. For example: `ManagedIdentityCredential` (cloud) and `AzureCliCredential` (local).2. You would rather build a custom list rather than use the `DefaultAzureCredentialOptions.Exclude...Credential` options.
It’s very easy to create your own chain. For example, with the Azure CLI for local and Managed Identity for cloud, you could new-up a `ChainedTokenCredential` object like this:
```csharp
var client = new SecretClient(vaultUri, new ChainedTokenCredential( new ManagedIdentityCredential(), new AzureCliCredential() ));This will tell the Azure Identity library to try to get a token from Managed Identity first and then Azure CLI. When building your own chain it is recommended that you try production credentials first followed by developer based credentials. That way developer credential types are never used in production.
Azure Identity Series
This post is part of the Azure Identity blog post series:
Azure Identity 101 - DefaultAzureCredential Azure Identity 201 - DefaultAzureCredential Options Azure Identity 202 - Environment Variables Azure Identity 301 - ChainedTokenCredential