microsoft-azure-webjobs-extensions-authentication-events-dot
microsoft/skills
Erweitern Sie die Microsoft Entra ID-Authentifizierungsflüsse mit benutzerdefinierten Ansprüchen, Attributsammlung und OTP-Bereitstellung unter Verwendung von Azure Functions-Auslösern.
...Alle erweiternMicrosoft.Azure.WebJobs.Extensions.AuthenticationEvents (.NET)
Azure Functions-Erweiterung zum Behandeln von benutzerdefinierten Microsoft Entra ID-Authentifizierungsereignissen.
Installation
dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents
Aktuelle Version: v1.1.0 (stabil)
Unterstützte Ereignisse
| Ereignis | Zweck |
|---|---|
| `OnTokenIssuanceStart` | Fügen Sie benutzerdefinierte Ansprüche während der Token-Ausstellung hinzu |
| `OnAttributeCollectionStart` | Passen Sie die Benutzeroberfläche zur Attributsammlung vor der Anzeige an |
| `OnAttributeCollectionSubmit` | Validieren oder ändern Sie Attribute nach der Benutzereingabe |
| `OnOtpSend` | Benutzerdefinierte OTP-Zustellung (SMS, E-Mail usw.) |
Hauptarbeitsabläufe
1. Token-Anreicherung (Benutzerdefinierte Ansprüche hinzufügen)
Fügen Sie während der Anmeldung benutzerdefinierte Ansprüche zu Zugriffs- oder ID-Token hinzu.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Extensions.Logging;
public static class TokenEnrichmentFunction
{
[FunctionName("OnTokenIssuanceStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
log.LogInformation("Token-Ausstellungsereignis für Benutzer: {UserId}",
request.Data?.AuthenticationContext?.User?.Id);
// Erstellen Sie die Antwort mit benutzerdefinierten Ansprüchen
var response = new WebJobsTokenIssuanceStartResponse();
// Fügen Sie Ansprüche zum Token hinzu
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string>
{
{ "customClaim1", "customValue1" },
{ "department", "Engineering" },
{ "costCenter", "CC-12345" },
{ "apiVersion", "v2" }
}
});
return response;
}
}
</string>2. Token-Anreicherung mit externen Daten
Rufen Sie Ansprüche aus externen Systemen (Datenbanken, APIs) ab.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Text.Json;
public static class TokenEnrichmentWithExternalData
{
private static readonly HttpClient _httpClient = new();
[FunctionName("OnTokenIssuanceStartExternal")]
public static async Task<webjobsauthenticationeventresponse> Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
string? userId = request.Data?.AuthenticationContext?.User?.Id;
if (string.IsNullOrEmpty(userId))
{
log.LogWarning("Keine Benutzer-ID in der Anfrage");
return new WebJobsTokenIssuanceStartResponse();
}
// Benutzerdaten von externer API abrufen
var userProfile = await GetUserProfileAsync(userId);
var response = new WebJobsTokenIssuanceStartResponse();
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string>
{
{ "employeeId", userProfile.EmployeeId },
{ "department", userProfile.Department },
{ "roles", string.Join(",", userProfile.Roles) }
}
});
return response;
}
private static async Task<userprofile> GetUserProfileAsync(string userId)
{
var response = await _httpClient.GetAsync($"https://api.example.com/users/{userId}");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<userprofile>(json)!;
}
}
public record UserProfile(string EmployeeId, string Department, string[] Roles);
</userprofile></userprofile></string></webjobsauthenticationeventresponse>3. Attributsammlung – Benutzeroberfläche anpassen (Start-Ereignis)
Passen Sie die Seite zur Attributsammlung an, bevor sie angezeigt wird.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Extensions.Logging;
public static class AttributeCollectionStartFunction
{
[FunctionName("OnAttributeCollectionStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsAttributeCollectionStartRequest request,
ILogger log)
{
log.LogInformation("Start der Attributsammlung für Korrelation: {CorrelationId}",
request.Data?.AuthenticationContext?.CorrelationId);
var response = new WebJobsAttributeCollectionStartResponse();
// Option 1: Mit Standardverhalten fortfahren
response.Actions.Add(new WebJobsContinueWithDefaultBehavior());
// Option 2: Attribute vorfüllen
// response.Actions.Add(new WebJobsSetPrefillValues
// {
// Attributes = new Dictionary<string>
// {
// { "city", "Seattle" },
// { "country", "USA" }
// }
// });
// Option 3: Sperrseite anzeigen (Anmeldung verhindern)
// response.Actions.Add(new WebJobsShowBlockPage
// {
// Message = "Die Anmeldung ist derzeit deaktiviert."
// });
return response;
}
}
</string>4. Attributsammlung – Übermittlung validieren (Übermittlungs-Ereignis)
Validieren und ändern Sie Attribute nach der Benutzereingabe.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Extensions.Logging;
public static class AttributeCollectionSubmitFunction
{
[FunctionName("OnAttributeCollectionSubmit")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsAttributeCollectionSubmitRequest request,
ILogger log)
{
var response = new WebJobsAttributeCollectionSubmitResponse();
// Auf die übermittelten Attribute zugreifen
var attributes = request.Data?.UserSignUpInfo?.Attributes;
string? email = attributes?["email"]?.ToString();
string? displayName = attributes?["displayName"]?.ToString();
// Validierungsbeispiel: Bestimmte E-Mail-Domänen blockieren
if (email?.EndsWith("@blocked.com") == true)
{
response.Actions.Add(new WebJobsShowBlockPage
{
Message = "Die Anmeldung von dieser E-Mail-Domäne ist nicht gestattet."
});
return response;
}
// Validierungsbeispiel: Validierungsfehler anzeigen
if (string.IsNullOrEmpty(displayName) || displayName.Length
{
{ "displayName", "Der Name ist zu kurz" }
}
});
return response;
}
// Attribute vor dem Speichern ändern
response.Actions.Add(new WebJobsModifyAttributeValues
{
Attributes = new Dictionary<string>
{
{ "displayName", displayName.Trim() },
{ "city", attributes?["city"]?.ToString()?.ToUpperInvariant() ?? "" }
}
});
return response;
}
}
</string>5. Benutzerdefinierte OTP-Zustellung
Senden Sie Einmalpasswörter (OTP) über benutzerdefinierte Kanäle (SMS, E-Mail, Push-Benachrichtigung).
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Extensions.Logging;
public static class CustomOtpFunction
{
[FunctionName("OnOtpSend")]
public static async Task<webjobsauthenticationeventresponse> Run(
[WebJobsAuthenticationEventsTrigger] WebJobsOnOtpSendRequest request,
ILogger log)
{
var response = new WebJobsOnOtpSendResponse();
string? phoneNumber = request.Data?.OtpContext?.Identifier;
string? otp = request.Data?.OtpContext?.OneTimeCode;
if (string.IsNullOrEmpty(phoneNumber) || string.IsNullOrEmpty(otp))
{
log.LogError("Fehlende Telefonnummer oder OTP");
response.Actions.Add(new WebJobsOnOtpSendFailed
{
Error = "Fehlende erforderliche Daten"
});
return response;
}
try
{
// OTP über Ihren SMS-Anbieter senden
await SendSmsAsync(phoneNumber, $"Ihr Bestätigungscode lautet: {otp}");
response.Actions.Add(new WebJobsOnOtpSendSuccess());
log.LogInformation("OTP erfolgreich gesendet an {PhoneNumber}", phoneNumber);
}
catch (Exception ex)
{
log.LogError(ex, "Fehler beim Senden des OTP");
response.Actions.Add(new WebJobsOnOtpSendFailed
{
Error = "Fehler beim Senden des Bestätigungscode"
});
}
return response;
}
private static async Task SendSmsAsync(string phoneNumber, string message)
{
// Implementieren Sie die Integration Ihres SMS-Anbieters (Twilio, Azure Communication Services usw.)
await Task.CompletedTask;
}
}
</webjobsauthenticationeventresponse>6. Konfiguration der Funktions-App
Konfigurieren Sie die Funktions-App für Authentifizierungsereignisse.
// Program.cs (Isolierter Arbeitsprozess-Modell)
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();
host.Run();
// host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true
}
}
},
"extensions": {
"http": {
"routePrefix": ""
}
}
}
// local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
Referenz zu wichtigen Typen
| Typ | Zweck |
|---|---|
| `WebJobsAuthenticationEventsTriggerAttribute` | Funktionsauslöser-Attribut |
| `WebJobsTokenIssuanceStartRequest` | Anfrage für Token-Ausstellungsereignis |
| `WebJobsTokenIssuanceStartResponse` | Antwort für Token-Ausstellungsereignis |
| `WebJobsProvideClaimsForToken` | Aktion zum Hinzufügen von Ansprüchen |
| `WebJobsAttributeCollectionStartRequest` | Anfrage zum Start der Attributsammlung |
| `WebJobsAttributeCollectionStartResponse` | Antwort zum Start der Attributsammlung |
| `WebJobsAttributeCollectionSubmitRequest` | Anfrage zur Attributübermittlung |
| `WebJobsAttributeCollectionSubmitResponse` | Antwort zur Attributübermittlung |
| `WebJobsSetPrefillValues` | Vorausfüllen von Formularwerten |
| `WebJobsShowBlockPage` | Benutzer mit Nachricht blockieren |
| `WebJobsShowValidationError` | Validierungsfehler anzeigen |
| `WebJobsModifyAttributeValues` | Übermittelte Werte ändern |
| `WebJobsOnOtpSendRequest` | Anfrage für OTP-Sendeereignis |
| `WebJobsOnOtpSendResponse` | Antwort für OTP-Sendeereignis |
| `WebJobsOnOtpSendSuccess` | OTP erfolgreich gesendet |
| `WebJobsOnOtpSendFailed` | OTP-Sendung fehlgeschlagen |
| `WebJobsContinueWithDefaultBehavior` | Mit dem Standardablauf fortfahren |
Entra ID-Konfiguration
Konfigurieren Sie nach dem Bereitstellen Ihrer Funktions-App die benutzerdefinierte Erweiterung in Entra ID:
- Registrieren Sie die API in Entra ID → App-Registrierungen
- Erstellen Sie eine benutzerdefinierte Authentifizierungserweiterung in Entra ID → Externe Identitäten → Benutzerdefinierte Authentifizierungserweiterungen
- Verknüpfen Sie sie mit dem Benutzerfluss in Entra ID → Externe Identitäten → Benutzerflüsse
Erforderliche Einstellungen für die App-Registrierung
API veröffentlichen:
- Anwendungs-ID-URI: api://<Ihr-Funktions-App-Name>.azurewebsites.net
- Bereich: CustomAuthenticationExtension.Receive.Payload
API-Berechtigungen:
- Microsoft Graph: User.Read (delegiert)
</your-function-app-name>Best Practices
- Validieren Sie alle Eingaben — Vertrauen Sie niemals auf Anfragedaten; validieren Sie vor der Verarbeitung
- Behandeln Sie Fehler angemessen — Geben Sie entsprechende Fehlerantworten zurück
- Protokollieren Sie Korrelations-IDs — Verwenden Sie
CorrelationIdzur Fehlerbehebung - Halten Sie Funktionen schnell — Authentifizierungsereignisse unterliegen Zeitlimiten
- Verwenden Sie verwaltete Identität — Greifen Sie sicher auf Azure-Ressourcen zu
- Zwischenspeichern Sie externe Daten — Vermeiden Sie langsame Suchen bei jeder Anfrage
- Testen Sie lokal — Verwenden Sie Azure Functions Core Tools mit Beispiel-Payloads
- Überwachen Sie mit App Insights — Verfolgen Sie die Funktionsausführung und Fehler
Fehlerbehandlung
[FunctionName("OnTokenIssuanceStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
try
{
// Ihre Logik hier
var response = new WebJobsTokenIssuanceStartResponse();
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string> { { "claim", "value" } }
});
return response;
}
catch (Exception ex)
{
log.LogError(ex, "Fehler bei der Verarbeitung des Token-Ausstellungsereignisses");
// Leere Antwort zurückgeben – die Authentifizierung wird ohne benutzerdefinierte Ansprüche fortgesetzt
// NICHT auslösen – dies würde die Authentifizierung fehlschlagen lassen
return new WebJobsTokenIssuanceStartResponse();
}
}
</string>Verwandte SDKs
| SDK | Zweck | Installation |
|---|---|---|
| `Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents` | Authentifizierungsereignisse (dieses SDK) | `dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents` |
| `Microsoft.Identity.Web` | Webanwendungsauthentifizierung | `dotnet add package Microsoft.Identity.Web` |
| `Azure.Identity` | Azure-Authentifizierung | `dotnet add package Azure.Identity` |
Referenzlinks
| Ressource | URL |
|---|---|
| NuGet-Paket | https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents |
| Übersicht zu benutzerdefinierten Erweiterungen | https://learn.microsoft.com/entra/identity-platform/custom-extension-overview |
| Token-Ausstellungsereignisse | https://learn.microsoft.com/entra/identity-platform/custom-extension-tokenissuancestart-setup |
| Attributsammelereignisse | https://learn.microsoft.com/entra/identity-platform/custom-extension-attribute-collection |
| GitHub-Quellcode | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/entra/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents |
---
name: microsoft-azure-webjobs-extensions-authentication-events-dot
description: Extend Microsoft Entra ID authentication flows with custom claims, attribute collection, and OTP delivery using Azure Functions triggers.
license: MIT
---
# Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents (.NET)
Azure Functions extension for handling Microsoft Entra ID custom authentication events.
## Installation
```bash
dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents
```
**Current Version**: v1.1.0 (stable)
## Supported Events
| Event | Purpose |
|-------|---------|
| `OnTokenIssuanceStart` | Add custom claims to tokens during issuance |
| `OnAttributeCollectionStart` | Customize attribute collection UI before display |
| `OnAttributeCollectionSubmit` | Validate/modify attributes after user submission |
| `OnOtpSend` | Custom OTP delivery (SMS, email, etc.) |
## Core Workflows
### 1. Token Enrichment (Add Custom Claims)
Add custom claims to access or ID tokens during sign-in.
```csharp
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Extensions.Logging;
public static class TokenEnrichmentFunction
{
[FunctionName("OnTokenIssuanceStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
log.LogInformation("Token issuance event for user: {UserId}",
request.Data?.AuthenticationContext?.User?.Id);
// Create response with custom claims
var response = new WebJobsTokenIssuanceStartResponse();
// Add claims to the token
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string, string>
{
{ "customClaim1", "customValue1" },
{ "department", "Engineering" },
{ "costCenter", "CC-12345" },
{ "apiVersion", "v2" }
}
});
return response;
}
}
```
### 2. Token Enrichment with External Data
Fetch claims from external systems (databases, APIs).
```csharp
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Text.Json;
public static class TokenEnrichmentWithExternalData
{
private static readonly HttpClient _httpClient = new();
[FunctionName("OnTokenIssuanceStartExternal")]
public static async Task<WebJobsAuthenticationEventResponse> Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
string? userId = request.Data?.AuthenticationContext?.User?.Id;
if (string.IsNullOrEmpty(userId))
{
log.LogWarning("No user ID in request");
return new WebJobsTokenIssuanceStartResponse();
}
// Fetch user data from external API
var userProfile = await GetUserProfileAsync(userId);
var response = new WebJobsTokenIssuanceStartResponse();
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string, string>
{
{ "employeeId", userProfile.EmployeeId },
{ "department", userProfile.Department },
{ "roles", string.Join(",", userProfile.Roles) }
}
});
return response;
}
private static async Task<UserProfile> GetUserProfileAsync(string userId)
{
var response = await _httpClient.GetAsync($"https://api.example.com/users/{userId}");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<UserProfile>(json)!;
}
}
public record UserProfile(string EmployeeId, string Department, string[] Roles);
```
### 3. Attribute Collection - Customize UI (Start Event)
Customize the attribute collection page before it's displayed.
```csharp
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Extensions.Logging;
public static class AttributeCollectionStartFunction
{
[FunctionName("OnAttributeCollectionStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsAttributeCollectionStartRequest request,
ILogger log)
{
log.LogInformation("Attribute collection start for correlation: {CorrelationId}",
request.Data?.AuthenticationContext?.CorrelationId);
var response = new WebJobsAttributeCollectionStartResponse();
// Option 1: Continue with default behavior
response.Actions.Add(new WebJobsContinueWithDefaultBehavior());
// Option 2: Prefill attributes
// response.Actions.Add(new WebJobsSetPrefillValues
// {
// Attributes = new Dictionary<string, string>
// {
// { "city", "Seattle" },
// { "country", "USA" }
// }
// });
// Option 3: Show blocking page (prevent sign-up)
// response.Actions.Add(new WebJobsShowBlockPage
// {
// Message = "Sign-up is currently disabled."
// });
return response;
}
}
```
### 4. Attribute Collection - Validate Submission (Submit Event)
Validate and modify attributes after user submission.
```csharp
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Extensions.Logging;
public static class AttributeCollectionSubmitFunction
{
[FunctionName("OnAttributeCollectionSubmit")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsAttributeCollectionSubmitRequest request,
ILogger log)
{
var response = new WebJobsAttributeCollectionSubmitResponse();
// Access submitted attributes
var attributes = request.Data?.UserSignUpInfo?.Attributes;
string? email = attributes?["email"]?.ToString();
string? displayName = attributes?["displayName"]?.ToString();
// Validation example: block certain email domains
if (email?.EndsWith("@blocked.com") == true)
{
response.Actions.Add(new WebJobsShowBlockPage
{
Message = "Sign-up from this email domain is not allowed."
});
return response;
}
// Validation example: show validation error
if (string.IsNullOrEmpty(displayName) || displayName.Length < 3)
{
response.Actions.Add(new WebJobsShowValidationError
{
Message = "Display name must be at least 3 characters.",
AttributeErrors = new Dictionary<string, string>
{
{ "displayName", "Name is too short" }
}
});
return response;
}
// Modify attributes before saving
response.Actions.Add(new WebJobsModifyAttributeValues
{
Attributes = new Dictionary<string, string>
{
{ "displayName", displayName.Trim() },
{ "city", attributes?["city"]?.ToString()?.ToUpperInvariant() ?? "" }
}
});
return response;
}
}
```
### 5. Custom OTP Delivery
Send one-time passwords via custom channels (SMS, email, push notification).
```csharp
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Extensions.Logging;
public static class CustomOtpFunction
{
[FunctionName("OnOtpSend")]
public static async Task<WebJobsAuthenticationEventResponse> Run(
[WebJobsAuthenticationEventsTrigger] WebJobsOnOtpSendRequest request,
ILogger log)
{
var response = new WebJobsOnOtpSendResponse();
string? phoneNumber = request.Data?.OtpContext?.Identifier;
string? otp = request.Data?.OtpContext?.OneTimeCode;
if (string.IsNullOrEmpty(phoneNumber) || string.IsNullOrEmpty(otp))
{
log.LogError("Missing phone number or OTP");
response.Actions.Add(new WebJobsOnOtpSendFailed
{
Error = "Missing required data"
});
return response;
}
try
{
// Send OTP via your SMS provider
await SendSmsAsync(phoneNumber, $"Your verification code is: {otp}");
response.Actions.Add(new WebJobsOnOtpSendSuccess());
log.LogInformation("OTP sent successfully to {PhoneNumber}", phoneNumber);
}
catch (Exception ex)
{
log.LogError(ex, "Failed to send OTP");
response.Actions.Add(new WebJobsOnOtpSendFailed
{
Error = "Failed to send verification code"
});
}
return response;
}
private static async Task SendSmsAsync(string phoneNumber, string message)
{
// Implement your SMS provider integration (Twilio, Azure Communication Services, etc.)
await Task.CompletedTask;
}
}
```
### 6. Function App Configuration
Configure the Function App for authentication events.
```csharp
// Program.cs (Isolated worker model)
using Microsoft.Extensions.Hosting;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();
host.Run();
```
```json
// host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true
}
}
},
"extensions": {
"http": {
"routePrefix": ""
}
}
}
```
```json
// local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
}
```
## Key Types Reference
| Type | Purpose |
|------|---------|
| `WebJobsAuthenticationEventsTriggerAttribute` | Function trigger attribute |
| `WebJobsTokenIssuanceStartRequest` | Token issuance event request |
| `WebJobsTokenIssuanceStartResponse` | Token issuance event response |
| `WebJobsProvideClaimsForToken` | Action to add claims |
| `WebJobsAttributeCollectionStartRequest` | Attribute collection start request |
| `WebJobsAttributeCollectionStartResponse` | Attribute collection start response |
| `WebJobsAttributeCollectionSubmitRequest` | Attribute submission request |
| `WebJobsAttributeCollectionSubmitResponse` | Attribute submission response |
| `WebJobsSetPrefillValues` | Prefill form values |
| `WebJobsShowBlockPage` | Block user with message |
| `WebJobsShowValidationError` | Show validation errors |
| `WebJobsModifyAttributeValues` | Modify submitted values |
| `WebJobsOnOtpSendRequest` | OTP send event request |
| `WebJobsOnOtpSendResponse` | OTP send event response |
| `WebJobsOnOtpSendSuccess` | OTP sent successfully |
| `WebJobsOnOtpSendFailed` | OTP send failed |
| `WebJobsContinueWithDefaultBehavior` | Continue with default flow |
## Entra ID Configuration
After deploying your Function App, configure the custom extension in Entra ID:
1. **Register the API** in Entra ID → App registrations
2. **Create Custom Authentication Extension** in Entra ID → External Identities → Custom authentication extensions
3. **Link to User Flow** in Entra ID → External Identities → User flows
### Required App Registration Settings
```
Expose an API:
- Application ID URI: api://<your-function-app-name>.azurewebsites.net
- Scope: CustomAuthenticationExtension.Receive.Payload
API Permissions:
- Microsoft Graph: User.Read (delegated)
```
## Best Practices
1. **Validate all inputs** — Never trust request data; validate before processing
2. **Handle errors gracefully** — Return appropriate error responses
3. **Log correlation IDs** — Use `CorrelationId` for troubleshooting
4. **Keep functions fast** — Authentication events have timeout limits
5. **Use managed identity** — Access Azure resources securely
6. **Cache external data** — Avoid slow lookups on every request
7. **Test locally** — Use Azure Functions Core Tools with sample payloads
8. **Monitor with App Insights** — Track function execution and errors
## Error Handling
```csharp
[FunctionName("OnTokenIssuanceStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
try
{
// Your logic here
var response = new WebJobsTokenIssuanceStartResponse();
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string, string> { { "claim", "value" } }
});
return response;
}
catch (Exception ex)
{
log.LogError(ex, "Error processing token issuance event");
// Return empty response - authentication continues without custom claims
// Do NOT throw - this would fail the authentication
return new WebJobsTokenIssuanceStartResponse();
}
}
```
## Related SDKs
| SDK | Purpose | Install |
|-----|---------|---------|
| `Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents` | Auth events (this SDK) | `dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents` |
| `Microsoft.Identity.Web` | Web app authentication | `dotnet add package Microsoft.Identity.Web` |
| `Azure.Identity` | Azure authentication | `dotnet add package Azure.Identity` |
## Reference Links
| Resource | URL |
|----------|-----|
| NuGet Package | https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents |
| Custom Extensions Overview | https://learn.microsoft.com/entra/identity-platform/custom-extension-overview |
| Token Issuance Events | https://learn.microsoft.com/entra/identity-platform/custom-extension-tokenissuancestart-setup |
| Attribute Collection Events | https://learn.microsoft.com/entra/identity-platform/custom-extension-attribute-collection |
| GitHub Source | https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/entra/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents |
Alle Dateien
1 Dateienmicrosoft-azure-webjobs-extensions-authentication-events-dot installieren
Laden Sie die Skill-Dateien herunter und extrahieren Sie diese in Ihr .claude/skills/-Verzeichnis.
ZIP herunterladenKlonen Sie das Repository und kopieren Sie die Skill-Dateien in Ihr Projekt.
git clone https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-dotnet/skills/microsoft-azure-webjobs-extensions-authentication-events-dotnet # Copy SKILL.md to your .claude/skills/ directory
Kopieren





Heim
