Questions
Users can't access an application after Entra ID configuration. Debug the authentication failure.
The Scenario
After configuring Entra ID (formerly Azure AD) for a new web application, users see:
AADSTS700016: Application with identifier 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
was not found in the directory 'contoso.com'. This can happen if the application
has not been installed by the administrator of the tenant or consented to by
any user in the tenant.
Some users get a different error:
AADSTS65001: The user or administrator has not consented to use the application
with ID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' named 'MyApp'.
The Challenge
Debug the authentication flow, fix app registration issues, and implement proper consent and permission configuration.
A junior engineer might recreate the app registration from scratch, grant admin consent for all permissions without understanding them, or disable security features to 'make it work'. These approaches lose existing configurations, create security risks, or mask underlying issues.
A senior engineer systematically checks the app registration configuration, validates redirect URIs, reviews permission scopes, implements proper consent flows, and uses Managed Identities where possible to eliminate credential management.
Step 1: Verify App Registration Exists
# Check if app registration exists
az ad app list --display-name "MyApp" --query "[].{Name:displayName,AppId:appId,Id:id}"
# If using service principal
az ad sp list --display-name "MyApp" --query "[].{Name:displayName,AppId:appId,Id:id}"
# Get detailed app registration info
az ad app show --id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"Step 2: Common Configuration Issues
# Check redirect URIs
az ad app show --id $APP_ID --query "web.redirectUris"
# Common mistakes:
# - HTTP instead of HTTPS (except localhost)
# - Missing trailing slash
# - Wrong port number
# - Case sensitivity issues
# Update redirect URIs
az ad app update --id $APP_ID \
--web-redirect-uris "https://myapp.azurewebsites.net/signin-oidc" \
"https://myapp.azurewebsites.net/.auth/login/aad/callback"Step 3: Check API Permissions and Consent
# List required permissions
az ad app permission list --id $APP_ID
# Check granted permissions (admin consent)
az ad app permission list-grants --id $APP_ID
# Grant admin consent for Microsoft Graph permissions
az ad app permission admin-consent --id $APP_IDStep 4: Understanding Permission Types
// Bicep template for app registration with proper permissions
resource appRegistration 'Microsoft.Graph/applications@v1.0' = {
displayName: 'MyApp'
signInAudience: 'AzureADMyOrg' // Single tenant
web: {
redirectUris: [
'https://myapp.azurewebsites.net/signin-oidc'
]
implicitGrantSettings: {
enableIdTokenIssuance: true
enableAccessTokenIssuance: false // Use auth code flow instead
}
}
requiredResourceAccess: [
{
// Microsoft Graph
resourceAppId: '00000003-0000-0000-c000-000000000000'
resourceAccess: [
{
// User.Read - Delegated
id: 'e1fe6dd8-ba31-4d61-89e7-88639da4683d'
type: 'Scope'
}
{
// Mail.Read - Delegated (requires admin consent)
id: '570282fd-fa5c-430d-a7fd-fc8dc98a9dca'
type: 'Scope'
}
]
}
]
}Step 5: Configure for Different Scenarios
Single Tenant (Enterprise App):
{
"signInAudience": "AzureADMyOrg",
"accessTokenAcceptedVersion": 2
}Multi-Tenant (SaaS):
{
"signInAudience": "AzureADMultipleOrgs",
"accessTokenAcceptedVersion": 2
}B2C Scenario:
{
"signInAudience": "AzureADandPersonalMicrosoftAccount",
"accessTokenAcceptedVersion": 2
}Step 6: Implement Managed Identity (Best Practice)
// Use Managed Identity to eliminate client secrets
resource webApp 'Microsoft.Web/sites@2022-03-01' = {
name: 'myapp'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
// ...
}
}
// Grant the managed identity access to Key Vault
resource keyVaultAccess 'Microsoft.KeyVault/vaults/accessPolicies@2022-07-01' = {
parent: keyVault
name: 'add'
properties: {
accessPolicies: [
{
tenantId: subscription().tenantId
objectId: webApp.identity.principalId
permissions: {
secrets: ['get', 'list']
}
}
]
}
}// C# code using Managed Identity
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
// No credentials needed - uses Managed Identity automatically
var client = new SecretClient(
new Uri("https://myvault.vault.azure.net/"),
new DefaultAzureCredential()
);
var secret = await client.GetSecretAsync("MySecret");Step 7: Debug Token Issues
# Decode and inspect JWT token
# Use https://jwt.ms or jwt.io
# Check token claims:
# - aud (audience) - must match your app ID
# - iss (issuer) - must be your tenant
# - exp (expiration) - must be in the future
# - scp or roles - must include required permissions
# Enable verbose logging in your app
export AZURE_LOG_LEVEL=verboseStep 8: Application Insights for Auth Debugging
// Add detailed authentication logging
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAd", options);
options.Events = new OpenIdConnectEvents
{
OnAuthenticationFailed = context =>
{
_logger.LogError(context.Exception,
"Authentication failed: {Message}",
context.Exception.Message);
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
_logger.LogInformation(
"Token validated for user: {User}",
context.Principal?.Identity?.Name);
return Task.CompletedTask;
}
};
}); Common AADSTS Error Codes
| Error Code | Cause | Fix |
|---|---|---|
| AADSTS700016 | App not found | Check app ID and tenant |
| AADSTS65001 | Consent required | Admin consent or user consent |
| AADSTS50011 | Redirect URI mismatch | Update redirect URIs |
| AADSTS7000218 | Missing client_assertion | Check client secret/cert |
| AADSTS90014 | Missing required field | Check request parameters |
Authentication Flow Comparison
| Flow | Use Case | Token Location |
|---|---|---|
| Auth Code | Web apps (server-side) | Backend only |
| Auth Code + PKCE | SPAs, mobile apps | Secure storage |
| Client Credentials | Service-to-service | Backend only |
| Implicit (deprecated) | Legacy SPAs | Don’t use |
Practice Question
Why should you use Managed Identity instead of service principal client secrets for Azure resources?