Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article provides guidelines on how to work with authentication when building Microsoft Fabric extensibility toolkit workloads. It includes information about working with tokens, consents, and accessing various services from your frontend application.
Before you begin, make sure you're familiar with the concepts in Authentication overview.
Frontend-only authentication model
The Extensibility Toolkit uses a frontend-only architecture that simplifies authentication compared to traditional workloads:
- Direct API calls: Your frontend directly calls Fabric APIs, Azure services, and external applications
- Token reuse: A single token can be used to authenticate against multiple Entra-secured services
- Simplified consent: Consent management is handled by the platform with automatic prompting
Microsoft Entra application configuration
Expose an API tab
Configure scopes for your workload application:
- Fabric integration scopes: Preauthorize Microsoft Power BI with application ID
871c010f-5e61-4fb1-83ac-98610a7e9110 - Custom API scopes: Add scopes for any custom APIs your workload exposes
- Granular permissions: Use different scopes for read vs. write operations
For example, if your workload exposes data APIs:
- Add
data.readscope for read operations - Add
data.writescope for write operations - Validate appropriate scopes in your API handlers
API permissions tab
Configure permissions for external services your workload needs to access:
- Required:
Fabric.Extendunder Power BI Service (mandatory for Fabric integration) - Azure services: Add scopes for Azure services like
https://storage.azure.com/user_impersonation - Custom applications: Add scopes for your own Entra-secured applications
- Third-party services: Include any external services that support Entra authentication
Token usage patterns
Using tokens for multiple services
The frontend token acquired through the Extensibility Toolkit can be used to authenticate against:
Fabric APIs
// Token automatically includes required Fabric scopes
const response = await fetch('https://api.fabric.microsoft.com/v1/workspaces', {
headers: {
'Authorization': `Bearer ${token.accessToken}`
}
});
Azure services
// Same token works for Azure services
const response = await fetch('https://management.azure.com/subscriptions', {
headers: {
'Authorization': `Bearer ${token.accessToken}`
}
});
Custom applications
// Token works for your own Entra-secured applications
const response = await fetch('https://myapp.contoso.com/api/data', {
headers: {
'Authorization': `Bearer ${token.accessToken}`
}
});
Scope management
The Extensibility Toolkit abstracts scope management for common scenarios:
- Fabric client libraries: Automatically include required Fabric scopes
- Azure client libraries: Handle Azure service scopes transparently
- Custom scopes: Specify additional scopes when needed
Working with consents
Initial token acquisition
Start by acquiring a token to establish the authentication context:
const token = await workloadClient.auth.acquireFrontendAccessToken({ scopes: [] });
This call may result in:
- Consent prompt: If the user hasn't consented to your application
- Silent acquisition: If consent was previously granted
Handling additional service access
When your workload needs to access additional services, specify the required scopes:
try {
// Request token with specific scopes for Azure Storage
const token = await workloadClient.auth.acquireFrontendAccessToken({
scopes: ['https://storage.azure.com/user_impersonation']
});
// Use token to access Azure Storage
const response = await fetch('https://mystorageaccount.blob.core.windows.net/', {
headers: { 'Authorization': `Bearer ${token.token}` }
});
} catch (error) {
// Handle authentication or authorization errors
console.error('Access failed:', error.message);
}
Example scenarios
Scenario 1: Accessing Fabric and Azure services
Your workload needs to:
- List Fabric workspaces
- Read from Azure Storage
- Write to Azure Key Vault
Implementation:
- Configure API permissions for required services
- Acquire initial token
- Use token for all service calls
- Handle consent prompts as needed
Scenario 2: Custom application integration
Your workload integrates with your own backend service:
- Configure your backend: Ensure it accepts Entra tokens
- Add API permissions: Include your backend's scopes in the workload application
- Use standard authentication: The same token pattern works for your custom services
Scenario 3: Third-party service integration
Integrating with external Entra-enabled services:
- Service registration: Register your workload with the third-party service
- Scope configuration: Add the service's scopes to your API permissions
- Token usage: Use the same authentication pattern for external services
Error handling and troubleshooting
Common authentication errors
- Consent required: User hasn't granted permission for a specific scope
- Conditional access: Additional authentication requirements (e.g., MFA)
- Token expiration: Token has expired and needs refresh
- Invalid scope: Requested scope isn't configured or available
Error handling patterns
async function handleAuthenticatedRequest(url: string, requiredScopes: string[] = []) {
try {
const token = await workloadClient.auth.acquireFrontendAccessToken({
scopes: requiredScopes
});
return await makeRequest(url, token);
} catch (error) {
if (error.code === 'consent_required') {
// User needs to grant consent for the requested scopes
console.error('Consent required for scopes:', requiredScopes);
}
throw error;
}
}
Redirect URI handling
The extensibility toolkit includes built-in redirect URI handling for authentication consent popups. This is implemented in the main index.ts file and handles consent redirects automatically.
The toolkit handles:
- Automatic window closure: Consent popups close automatically after user interaction
- Error handling: Specific error codes are detected and handled appropriately
- Error display: Failed consent attempts show user-friendly error messages
Current implementation in the toolkit:
const redirectUriPath = '/close';
const url = new URL(window.location.href);
if (url.pathname?.startsWith(redirectUriPath)) {
// Handle errors
if (url?.hash?.includes("error")) {
if (url.hash.includes("AADSTS650052")) {
// Handle missing service principal error
printFormattedAADErrorMessage(url?.hash);
} else if (url.hash.includes("AADSTS65004")) {
// Handle user declined consent error
printFormattedAADErrorMessage(url?.hash);
} else {
window.close();
}
} else {
// Close window on successful consent
window.close();
}
}
Note
The redirect URI handling is automatically included in the extensibility toolkit template. You don't need to implement this yourself unless you want to customize the error handling behavior.
Best practices
Token management
- Cache tokens: Reuse tokens until they expire
- Handle refresh: Implement automatic token refresh logic
- Secure storage: Store tokens securely in browser memory
Consent management
- Minimal permissions: Request only the scopes you actually need
- Progressive consent: Request additional permissions as features are used
- Clear messaging: Explain to users why permissions are needed
Error handling
- Graceful degradation: Provide fallback functionality when possible
- User feedback: Clearly communicate authentication requirements
- Retry logic: Implement appropriate retry mechanisms for transient failures