Your enterprise web apps often need to serve both corporate users and customers. Here’s how to configure dual authentication in Azure App Service—without writing a single line of auth middleware.
🔑 Key Features
- Single-tenant and multi-tenant authentication support
- Automatic token validation and session management
- Built-in token store for session persistence
- Support for custom domains in authentication endpoints
- Integration with Azure Monitor for auth telemetry
TL;DR
# Clone the repo
git clone https://github.com/taofik-ib/AzureARM-Projects/tree/main/Azure-app-service-Auth
Why This Matters
Modern web applications frequently need to support multiple authentication flows:
User Type | Identity Solution | Key Benefits |
---|---|---|
Employees & Partners | Microsoft Entra ID | • Single sign-on with corporate accounts • Conditional Access policies • Group-based authorization |
Customers | Azure AD B2C | • Social login support • Custom branding • Progressive user profiling |
The challenge? Configuring both providers traditionally requires complex middleware and careful coordination. This guide shows you how to achieve it using pure infrastructure as code.
Prerequisites
- Azure subscription with Contributor access
- For B2C setup: A tenant with a sign-up/sign-in user flow
- App registrations created in both directories
💡 Pro Tip: Store your client secrets in Key Vault and reference them via
@Microsoft.KeyVault(...)
in your template.
Setting Up Microsoft Entra ID Authentication
1. Set the Parameters
The template’s core configuration starts with the authType
parameter. This parameter determines which identity provider to enable, allowing you to toggle between Microsoft Entra ID and Azure AD B2C authentication flows:
"authType": {
"allowedValues": [
"AzureAD",
"AzureADB2C"
],
"type": "string",
"metadata": {
"description": "The type of authentication to use. Choose between AzureAD and AzureADB2C."
}
},
This parameter drives conditional resource provisioning throughout the template, enabling either workforce or customer identity scenarios.
2. Configure the Variables
The ARM template uses variables to construct dynamic values and configure the authentication providers. These variables define the App Service naming convention and set up the OpenID Connect endpoints:
"variables": {
"webAppPortalName": "[format('{0}-webapp', parameters('webAppName'))]",
"appServicePlanName": "[format('AppServicePlan-{0}', parameters('webAppName'))]",
// Key configuration: Points to the App Service's V2 auth settings resource
"authSettingsName": "[concat(parameters('appServiceName'), '/authsettingsV2')]",
// Constructs the OpenID Connect issuer URL for your tenant
// This forms the base URL for all authentication endpoints
"OpenIdIssuerUrl": "[concat(environment().authentication.loginEndpoint, '/', parameters('tenantId'), '/v2.0')]",
"azureADSettings": {
"enabled": "[if(equals(parameters('authType'), 'AzureAD'), true(), false())]",
"registration": {
"clientId": "[parameters('clientId')]",
"clientSecretSettingName": "MICROSOFT_PROVIDER_AUTHENTICATION_SECRET",
"openIdIssuer": "[variables('OpenIdIssuerUrl')]"
},
"login": {
"disableWWWAuthenticate": false
},
"validation": {
"allowedAudiences": "[parameters('allowedAudiences')]",
"allowedApplications": "[parameters('allowedApplications')]"
}
}
}
3. Add Required Parameters
The parameters file (parameters.json
) contains the configuration values needed for your authentication setup. Here’s a breakdown of the essential parameters:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
// Unique name for your App Service
"webAppName": {
"value": "AuthAppService01"
},
// Authentication type: 'AzureAD' for workforce or 'AzureADB2C' for customer identities
"authType": {
"value": "AzureAD"
},
// Application (client) ID from your app registration
"clientId": {
"value": "Your Client Id"
},
// Node.js version for the App Service
"runtimeVersion": {
"value": "~1"
}
}
}
🔐 Security Best Practices:
- Store sensitive values like
clientSecret
in Key Vault- Use managed identities for Key Vault access
- Keep separate parameter files for different environments
- Enable diagnostic settings for auth logging
- Configure minimum TLS version 1.2
- Set up IP restrictions alongside auth
Additional parameters you might need:
tenantId
: Your Azure AD tenant ID (required for Entra ID)allowedAudiences
: List of allowed app IDs that can access your appallowedApplications
: Specific applications permitted to access your APIb2cTenantName
: Your B2C tenant name (required for B2C setup)b2cPolicy
: Name of your sign-up/sign-in policy (e.g., “B2C_1_susi”)
These parameters drive the conditional logic in the template, determining which authentication provider to enable and how it should be configured.
Authentication Flows and Endpoints
Default Authentication Flow
App Service URL → /.auth/login/<provider> → Identity Provider → /.auth/login/callback
Custom Domain Authentication
https://your-domain.com → /.auth/login/aad → Entra ID → your-domain.com/.auth/login/callback
Available Authentication Endpoints
/.auth/login/<provider>
- Initiate login/.auth/logout
- Sign out user/.auth/refresh
- Refresh access token/.auth/me
- Get current user info
Common Issues and Solutions
Issue | Solution |
---|---|
Token validation errors | Check issuer URL and audience configuration |
CORS errors | Add allowed origins in authentication settings |
Session persistence issues | Enable token store and check storage permissions |
B2C policy errors | Verify policy name and tenant configuration |
Advanced Configuration Options
Once you have the basic authentication working, you can enhance your setup with these advanced features:
1. Token Store Configuration
Use this to enable session persistence and configure token lifetime:
"tokenStore": {
"enabled": true,
"tokenRefreshExtensionHours": 72,
"fileSystem": {
"directory": "/.auth/tokens"
}
}
2. Custom Domain Support
Configure authentication endpoints with your custom domain:
"identityProviders": {
"customOpenIdConnectProviders": {
"name": "your-custom-domain",
"registration": {
"openIdConnectConfiguration": {
"issuer": "https://login.yourdomain.com"
}
}
}
}
3. Advanced Logging
Enable detailed authentication logging for monitoring and troubleshooting:
"diagnosticSettings": {
"logs": [
{
"category": "AppServiceAuthenticationLogs",
"enabled": true
}
]
}
Security Considerations
-
Token Configuration
- Set appropriate token lifetime
- Configure refresh token behavior
- Enable token store encryption
-
Network Security
- Enable Azure Front Door WAF
- Configure IP restrictions
- Set up DDoS protection
-
Monitoring
- Enable authentication logging
- Set up alerts for authentication failures
- Monitor token usage and expiration
Next Steps
After implementing authentication:
-
Enhanced Security
- Implement Conditional Access policies
- Set up MFA for sensitive operations
- Configure risk-based authentication
-
Custom Branding
- Add company logo to login pages
- Customize error pages
- Implement custom domains
-
Advanced Scenarios
- Configure hybrid flows
- Implement step-up authentication
- Set up claims transformation
Resources
- Easy Auth documentation
- B2C custom domain setup
- Sample repo with complete setup
- Authentication troubleshooting guide
- Security best practices