Skip to content

Commit

Permalink
update docs. (#34306)
Browse files Browse the repository at this point in the history
  • Loading branch information
g2vinay committed Apr 10, 2023
1 parent 283baea commit 86b8c90
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 29 deletions.
34 changes: 34 additions & 0 deletions sdk/identity/azure-identity/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ This troubleshooting guide covers failure investigation techniques, common error
- [Azure App Service and Azure Functions Managed Identity](#azure-app-service-and-azure-functions-managed-identity)
- [Troubleshoot VisualStudioCodeCredential authentication issues](#troubleshoot-visualstudiocodecredential-authentication-issues)
- [Troubleshoot AzureCliCredential authentication issues](#troubleshoot-azureclicredential-authentication-issues)
- [Troubleshoot AzureDeveloperCliCredential authentication issues](#troubleshoot-azuredeveloperclicredential-authentication-issues)
- [Troubleshoot AzurePowerShellCredential authentication issues](#troubleshoot-azurepowershellcredential-authentication-issues)
- [Troubleshoot WorkloadIdentityCredential authentication issues](#troubleshoot-workloadidentitycredential-authentication-issues)
- [Get additional help](#get-additional-help)

## Handle Azure Identity exceptions
Expand Down Expand Up @@ -210,6 +212,31 @@ az account get-access-token --output json --resource https://management.core.win
```
>Note that output of this command will contain a valid access token, and SHOULD NOT BE SHARED to avoid compromising account security.

## Troubleshoot `AzureDeveloperCliCredential` authentication issues

`CredentialUnavailableException`

| Error Message |Description| Mitigation |
|---|---|---|
|Azure Developer CLI not installed|The Azure Developer CLI isn't installed or couldn't be found.|<ul><li>Ensure the Azure Developer CLI is properly installed. Installation instructions can be found [here](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd).</li><li>Validate the installation location has been added to the `PATH` environment variable.</li></ul>|
|Please run 'azd login' to set up account|No account is currently logged into the Azure Developer CLI, or the login has expired.|<ul><li>Log into the Azure Developer CLI using the `azd login` command.</li><li>Validate that the Azure Developer CLI can obtain tokens. See [below](#verify-the-azure-developer-cli-can-obtain-tokens) for instructions.</li></ul>|

#### Verify the Azure Developer CLI can obtain tokens

You can manually verify that the Azure Developer CLI is properly authenticated, and can obtain tokens. First use the `config` command to verify the account which is currently logged in to the Azure Developer CLI.

```bash
azd config list
```

Once you've verified the Azure Developer CLI is using correct account, you can validate that it's able to obtain tokens for this account.

```bash
azd auth token --output json --scope https://management.core.windows.net/.default
```
>Note that output of this command will contain a valid access token, and SHOULD NOT BE SHARED to avoid compromising account security.
## Troubleshoot `AzurePowerShellCredential` authentication issues

`CredentialUnavailableException`
Expand Down Expand Up @@ -239,6 +266,13 @@ Get-AzAccessToken -ResourceUrl "https://management.core.windows.net"
```
>Note that output of this command will contain a valid access token, and SHOULD NOT BE SHARED to avoid compromising account security.

## Troubleshoot `WorkloadIdentityCredential` authentication issues

| Error |Description| Mitigation |
|---|---|---|
|`CredentialUnavailableException` raised with message. "WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured."|The `WorkloadIdentityCredential` requires `clientId`, `tenantId` and `tokenFilePath` to authenticate with Azure Active Directory.| <ul><li>If using `DefaultAzureCredential` then:</li><ul><li>Ensure client ID is specified via `workloadIdentityClientId` setter or `AZURE_CLIENT_ID` env variable.</li><li>Ensure tenant ID is specified via `AZURE_TENANT_ID` env variable.</li><li>Ensure token file path is specified via `AZURE_FEDERATED_TOKEN_FILE` env variable.</li><li>Ensure authority host is specified via `AZURE_AUTHORITY_HOST` env variable.</ul><li>If using `WorkloadIdentityCredential` then:</li><ul><li>Ensure tenant ID is specified via `tenantId` setter on credential builder or `AZURE_TENANT_ID` env variable.</li><li>Ensure client ID is specified via `clientId` setter on the credential builder or `AZURE_CLIENT_ID` env variable.</li><li>Ensure token file path is specified via `tokenFilePath` setter on the credential builder or `AZURE_FEDERATED_TOKEN_FILE` environment variable. </li></ul></li><li>Consult the [product troubleshooting guide](https://azure.github.io/azure-workload-identity/docs/troubleshooting.html) for other issues.</li></ul>

## Troubleshoot multi-tenant authentication issues
`ClientAuthenticationException`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,46 @@
import reactor.core.publisher.Mono;

/**
* A credential provider that provides token credentials based on Azure Developer CLI
* command.
* <p>Azure Developer CLI is a command-line interface tool that allows developers to create, manage, and deploy
* resources in Azure. It's built on top of the Azure CLI and provides additional functionality specific
* to Azure developers. It allows users to authenticate as a user and/or a service principal against
* <a href="https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/">Azure Active Directory (Azure AD)
* </a>. The AzureDeveloperCliCredential authenticates in a development environment and acquires a token on behalf of
* the logged-in user or service principal in Azure Developer CLI. It acts as the Azure Developer CLI logged in user or
* service principal and executes an Azure CLI command underneath to authenticate the application against
* Azure Active Directory.</p>
*
* <h2>Configure AzureDeveloperCliCredential</h2>
*
* <p> To use this credential, the developer needs to authenticate locally in Azure Developer CLI using one of the
* commands below:</p>
*
* <ol>
* <li>Run "azd login" in Azure Developer CLI to authenticate interactively as a user.</li>
* <li>Run "azd login --client-id {@code clientID} --client-secret {@code clientSecret}
* --tenant-id {@code tenantID}" to authenticate as a service principal.</li>
* </ol>
*
* <p>You may need to repeat this process after a certain time period, depending on the refresh token validity in your
* organization. Generally, the refresh token validity period is a few weeks to a few months.
* AzureDeveloperCliCredential will prompt you to sign in again.</p>
*
* <p><strong>Sample: Construct AzureDeveloperCliCredential</strong></p>
*
* <p>The following code sample demonstrates the creation of a {@link com.azure.identity.AzureDeveloperCliCredential},
* using the {@link com.azure.identity.AzureDeveloperCliCredentialBuilder} to configure it. Once this credential is
* created, it may be passed into the builder of many of the Azure SDK for Java client builders as the 'credential'
* parameter.</p>
*
* <!-- src_embed com.azure.identity.credential.azuredeveloperclicredential.construct -->
* <pre>
* TokenCredential azureDevCliCredential = new AzureDeveloperCliCredentialBuilder&#40;&#41;
* .build&#40;&#41;;
* </pre>
* <!-- end com.azure.identity.credential.azuredeveloperclicredential.construct -->
*
* @see com.azure.identity
* @see AzureDeveloperCliCredentialBuilder
*/
@Immutable
public class AzureDeveloperCliCredential implements TokenCredential {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@
/**
* Fluent credential builder for instantiating a {@link AzureDeveloperCliCredential}.
*
* <p>Azure Developer CLI is a command-line interface tool that allows developers to create, manage, and deploy
* resources in Azure. It's built on top of the Azure CLI and provides additional functionality specific
* to Azure developers. It allows users to authenticate as a user and/or a service principal against
* <a href="https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/">Azure Active Directory (Azure AD)
* </a>. The AzureDeveloperCliCredential authenticates in a development environment and acquires a token on behalf of
* the logged-in user or service principal in Azure Developer CLI. It acts as the Azure Developer CLI logged in user or
* service principal and executes an Azure CLI command underneath to authenticate the application against
* Azure Active Directory.</p>
*
* <p><strong>Sample: Construct AzureDeveloperCliCredential</strong></p>
*
* <p>The following code sample demonstrates the creation of a {@link com.azure.identity.AzureDeveloperCliCredential},
* using the {@link com.azure.identity.AzureDeveloperCliCredentialBuilder} to configure it. Once this credential is
* created, it may be passed into the builder of many of the Azure SDK for Java client builders as the 'credential'
* parameter.</p>
*
* <!-- src_embed com.azure.identity.credential.azuredeveloperclicredential.construct -->
* <pre>
* TokenCredential azureDevCliCredential = new AzureDeveloperCliCredentialBuilder&#40;&#41;
* .build&#40;&#41;;
* </pre>
* <!-- end com.azure.identity.credential.azuredeveloperclicredential.construct -->
*
* @see AzureDeveloperCliCredential
*/
public class AzureDeveloperCliCredentialBuilder extends CredentialBuilderBase<AzureDeveloperCliCredentialBuilder> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;

import static com.azure.identity.ManagedIdentityCredential.AZURE_FEDERATED_TOKEN_FILE;

/**
* <p>Fluent credential builder for instantiating a {@link DefaultAzureCredential}.</p>
*
Expand Down Expand Up @@ -266,12 +264,9 @@ private void loadFallbackValuesFromEnvironment() {
}

private ArrayList<TokenCredential> getCredentialsChain() {
WorkloadIdentityCredential workloadIdentityCredential = getWorkloadIdentityCredentialIfAvailable();
ArrayList<TokenCredential> output = new ArrayList<TokenCredential>(workloadIdentityCredential != null ? 8 : 7);
ArrayList<TokenCredential> output = new ArrayList<TokenCredential>(8);
output.add(new EnvironmentCredential(identityClientOptions.clone()));
if (workloadIdentityCredential != null) {
output.add(workloadIdentityCredential);
}
output.add(getWorkloadIdentityCredential());
output.add(new ManagedIdentityCredential(managedIdentityClientId, managedIdentityResourceId, identityClientOptions.clone()));
output.add(new AzureDeveloperCliCredential(tenantId, identityClientOptions.clone()));
output.add(new SharedTokenCacheCredential(null, IdentityConstants.DEVELOPER_SINGLE_SIGN_ON_ID,
Expand All @@ -282,20 +277,18 @@ private ArrayList<TokenCredential> getCredentialsChain() {
return output;
}

private WorkloadIdentityCredential getWorkloadIdentityCredentialIfAvailable() {
private WorkloadIdentityCredential getWorkloadIdentityCredential() {
Configuration configuration = identityClientOptions.getConfiguration() == null
? Configuration.getGlobalConfiguration().clone() : identityClientOptions.getConfiguration();

String tenantId = configuration.get(Configuration.PROPERTY_AZURE_TENANT_ID);
String federatedTokenFilePath = configuration.get(AZURE_FEDERATED_TOKEN_FILE);
String azureAuthorityHost = configuration.get(Configuration.PROPERTY_AZURE_AUTHORITY_HOST);
String clientId = CoreUtils.isNullOrEmpty(workloadIdentityClientId) ? managedIdentityClientId : workloadIdentityClientId;
if (!(CoreUtils.isNullOrEmpty(tenantId)
|| CoreUtils.isNullOrEmpty(federatedTokenFilePath)
|| CoreUtils.isNullOrEmpty(clientId)
|| CoreUtils.isNullOrEmpty(azureAuthorityHost))) {
return new WorkloadIdentityCredential(tenantId, clientId, federatedTokenFilePath, identityClientOptions.setAuthorityHost(azureAuthorityHost).clone());
String clientId = CoreUtils.isNullOrEmpty(workloadIdentityClientId)
? managedIdentityClientId : workloadIdentityClientId;

if (!CoreUtils.isNullOrEmpty(azureAuthorityHost)) {
identityClientOptions.setAuthorityHost(azureAuthorityHost);
}
return null;
return new WorkloadIdentityCredential(null, clientId, null,
identityClientOptions.clone());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,50 @@
import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;
import com.azure.core.util.Configuration;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
import com.azure.identity.implementation.IdentityClient;
import com.azure.identity.implementation.IdentityClientBuilder;
import com.azure.identity.implementation.IdentityClientOptions;
import com.azure.identity.implementation.util.ValidationUtil;
import reactor.core.publisher.Mono;

import static com.azure.identity.ManagedIdentityCredential.AZURE_FEDERATED_TOKEN_FILE;

/**
* WorkloadIdentityCredential supports Azure workload identity authentication on Kubernetes.
* Refer to <a href="https://learn.microsoft.com/azure/aks/workload-identity-overview">Azure Active Directory Workload Identity</a>
* for more information.
* <p>Workload Identity authentication is a feature in Azure that allows applications running on virtual machines (VMs)
* to access other Azure resources without the need for a service principal or managed identity. With Workload Identity
* authentication, applications authenticate themselves using their own identity, rather than using a shared service
* principal or managed identity. Under the hood, Workload Identity authentication uses the concept of Service Account
* Credentials (SACs), which are automatically created by Azure and stored securely in the VM. By using Workload
* Identity authentication, you can avoid the need to manage and rotate service principals or managed identities for
* each application on each VM. Additionally, because SACs are created automatically and managed by Azure, you don't
* need to worry about storing and securing sensitive credentials themselves.
* The WorkloadIdentityCredential supports Azure workload identity authentication on Azure Kubernetes and acquires
* a token using the service account credentials available in the Azure Kubernetes environment.
* Refer to <a href="https://learn.microsoft.com/azure/aks/workload-identity-overview">Azure Active Directory
* Workload Identity</a> for more information.</p>
*
* <p><strong>Sample: Construct WorkloadIdentityCredential</strong></p>
*
* <p>The following code sample demonstrates the creation of a {@link WorkloadIdentityCredential},
* using the {@link WorkloadIdentityCredentialBuilder} to configure it. The {@code clientId},
* is required to create {@link WorkloadIdentityCredential}. Once this credential is created, it may be passed into the
* builder of many of the Azure SDK for Java client builders as the 'credential' parameter.</p>
*
* <!-- src_embed com.azure.identity.credential.workloadidentitycredential.construct -->
* <pre>
* TokenCredential onBehalfOfCredential = new WorkloadIdentityCredentialBuilder&#40;&#41;
* .clientId&#40;&quot;&lt;clientID&gt;&quot;&#41;
* .tenantId&#40;&quot;&lt;tenantID&gt;&quot;&#41;
* .tokenFilePath&#40;&quot;&lt;token-file-path&gt;&quot;&#41;
* .build&#40;&#41;;
* </pre>
* <!-- end com.azure.identity.credential.workloadidentitycredential.construct -->
*
* @see com.azure.identity
* @see WorkloadIdentityCredentialBuilder
*/
public class WorkloadIdentityCredential implements TokenCredential {
private static final ClientLogger LOGGER = new ClientLogger(WorkloadIdentityCredential.class);
Expand All @@ -32,16 +65,42 @@ public class WorkloadIdentityCredential implements TokenCredential {
*/
WorkloadIdentityCredential(String tenantId, String clientId, String federatedTokenFilePath, IdentityClientOptions identityClientOptions) {
ValidationUtil.validateTenantIdCharacterRange(tenantId, LOGGER);
identityClient = new IdentityClientBuilder()
.clientAssertionPath(federatedTokenFilePath)
.clientId(clientId)
.tenantId(tenantId)
.identityClientOptions(identityClientOptions)
.build();

Configuration configuration = identityClientOptions.getConfiguration() == null
? Configuration.getGlobalConfiguration().clone() : identityClientOptions.getConfiguration();

String tenantIdInput = CoreUtils.isNullOrEmpty(tenantId)
? configuration.get(Configuration.PROPERTY_AZURE_TENANT_ID) : tenantId;

String federatedTokenFilePathInput = CoreUtils.isNullOrEmpty(federatedTokenFilePath)
? configuration.get(AZURE_FEDERATED_TOKEN_FILE) : federatedTokenFilePath;

String clientIdInput = CoreUtils.isNullOrEmpty(clientId)
? configuration.get(Configuration.PROPERTY_AZURE_CLIENT_ID) : clientId;

if (!(CoreUtils.isNullOrEmpty(tenantIdInput)
|| CoreUtils.isNullOrEmpty(federatedTokenFilePathInput)
|| CoreUtils.isNullOrEmpty(clientIdInput)
|| CoreUtils.isNullOrEmpty(identityClientOptions.getAuthorityHost()))) {
identityClient = new IdentityClientBuilder()
.clientAssertionPath(federatedTokenFilePathInput)
.clientId(clientId)
.tenantId(tenantIdInput)
.identityClientOptions(identityClientOptions)
.build();
} else {
identityClient = null;
}
}

@Override
public Mono<AccessToken> getToken(TokenRequestContext request) {
if (identityClient == null) {
return Mono.error(LOGGER.logExceptionAsError(new CredentialUnavailableException("WorkloadIdentityCredential"
+ " authentication unavailable. The workload options are not fully configured. See the troubleshooting"
+ " guide for more information."
+ " https://aka.ms/azsdk/java/identity/workloadidentitycredential/troubleshoot")));
}
return identityClient.authenticateWithExchangeToken(request);
}

Expand Down

0 comments on commit 86b8c90

Please sign in to comment.