microsoft-azure-webjobs-extensions-authentication-events-dot
microsoft/skills
Расширьте потоки аутентификации Microsoft Entra ID с помощью пользовательских заявлений, сбора атрибутов и доставки одноразовых паролей (OTP) с помощью триггеров Azure Functions.
...Расширить всеMicrosoft.Azure.WebJobs.Extensions.AuthenticationEvents (.NET)
Расширение Azure Functions для обработки пользовательских событий аутентификации Microsoft Entra ID.
Установка
dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents
Текущая версия: v1.1.0 (стабильная)
Поддерживаемые события
| Событие | Назначение |
|---|---|
| `OnTokenIssuanceStart` | Добавление пользовательских утверждений (claims) в токены в процессе выдачи |
| `OnAttributeCollectionStart` | Настройка интерфейса сбора атрибутов перед отображением |
| `OnAttributeCollectionSubmit` | Проверка/изменение атрибутов после отправки пользователем |
| `OnOtpSend` | Пользовательская доставка одноразовых паролей (SMS, электронная почта и т. д.) |
Основные рабочие процессы
1. Обогащение токена (Добавление пользовательских утверждений)
Добавление пользовательских утверждений в токены доступа или токены идентификатора (ID) во время входа в систему.
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("Событие выдачи токена для пользователя: {UserId}",
request.Data?.AuthenticationContext?.User?.Id);
// Создание ответа с пользовательскими утверждениями
var response = new WebJobsTokenIssuanceStartResponse();
// Добавление утверждений в токен
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string>
{
{ "customClaim1", "customValue1" },
{ "department", "Engineering" },
{ "costCenter", "CC-12345" },
{ "apiVersion", "v2" }
}
});
return response;
}
}
</string>2. Обогащение токена с внешними данными
Получение утверждений из внешних систем (базы данных, API).
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("В запросе отсутствует идентификатор пользователя");
return new WebJobsTokenIssuanceStartResponse();
}
// Получение данных пользователя из внешнего API
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. Сбор атрибутов — Настройка интерфейса (Событие начала)
Настройка страницы сбора атрибутов перед её отображением.
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("Начало сбора атрибутов для корреляции: {CorrelationId}",
request.Data?.AuthenticationContext?.CorrelationId);
var response = new WebJobsAttributeCollectionStartResponse();
// Вариант 1: Продолжить со стандартным поведением
response.Actions.Add(new WebJobsContinueWithDefaultBehavior());
// Вариант 2: Предварительно заполнить атрибуты
// response.Actions.Add(new WebJobsSetPrefillValues
// {
// Attributes = new Dictionary<string>
// {
// { "city", "Seattle" },
// { "country", "USA" }
// }
// });
// Вариант 3: Отобразить блокирующую страницу (запретить регистрацию)
// response.Actions.Add(new WebJobsShowBlockPage
// {
// Message = "Регистрация в настоящее время отключена."
// });
return response;
}
}
</string>4. Сбор атрибутов — Проверка отправки (Событие отправки)
Проверка и изменение атрибутов после отправки пользователем.
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();
// Доступ к отправленным атрибутам
var attributes = request.Data?.UserSignUpInfo?.Attributes;
string? email = attributes?["email"]?.ToString();
string? displayName = attributes?["displayName"]?.ToString();
// Пример проверки: блокировка определенных доменов электронной почты
if (email?.EndsWith("@blocked.com") == true)
{
response.Actions.Add(new WebJobsShowBlockPage
{
Message = "Регистрация с этого домена электронной почты не разрешена."
});
return response;
}
// Пример проверки: отображение ошибки валидации
if (string.IsNullOrEmpty(displayName) || displayName.Length
{
{ "displayName", "Имя слишком короткое" }
}
});
return response;
}
// Изменение атрибутов перед сохранением
response.Actions.Add(new WebJobsModifyAttributeValues
{
Attributes = new Dictionary<string>
{
{ "displayName", displayName.Trim() },
{ "city", attributes?["city"]?.ToString()?.ToUpperInvariant() ?? "" }
}
});
return response;
}
}
</string>5. Пользовательская доставка OTP
Отправка одноразовых паролей через пользовательские каналы (SMS, электронная почта, push-уведомления).
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("Отсутствует номер телефона или OTP");
response.Actions.Add(new WebJobsOnOtpSendFailed
{
Error = "Отсутствуют необходимые данные"
});
return response;
}
try
{
// Отправка OTP через вашего провайдера SMS
await SendSmsAsync(phoneNumber, $"Ваш код подтверждения: {otp}");
response.Actions.Add(new WebJobsOnOtpSendSuccess());
log.LogInformation("OTP успешно отправлен на {PhoneNumber}", phoneNumber);
}
catch (Exception ex)
{
log.LogError(ex, "Не удалось отправить OTP");
response.Actions.Add(new WebJobsOnOtpSendFailed
{
Error = "Не удалось отправить код подтверждения"
});
}
return response;
}
private static async Task SendSmsAsync(string phoneNumber, string message)
{
// Реализуйте интеграцию с вашим провайдером SMS (Twilio, Azure Communication Services и т. д.)
await Task.CompletedTask;
}
}
</webjobsauthenticationeventresponse>6. Конфигурация приложения функций
Настройка приложения функций для событий аутентификации.
// Program.cs (Модель изолированного рабочего процесса)
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"
}
}
Справочник основных типов
| Тип | Назначение |
|---|---|
| `WebJobsAuthenticationEventsTriggerAttribute` | Атрибут триггера функции |
| `WebJobsTokenIssuanceStartRequest` | Запрос события выдачи токена |
| `WebJobsTokenIssuanceStartResponse` | Ответ события выдачи токена |
| `WebJobsProvideClaimsForToken` | Действие по добавлению утверждений |
| `WebJobsAttributeCollectionStartRequest` | Запрос начала сбора атрибутов |
| `WebJobsAttributeCollectionStartResponse` | Ответ начала сбора атрибутов |
| `WebJobsAttributeCollectionSubmitRequest` | Запрос отправки атрибутов |
| `WebJobsAttributeCollectionSubmitResponse` | Ответ отправки атрибутов |
| `WebJobsSetPrefillValues` | Предварительное заполнение значений формы |
| `WebJobsShowBlockPage` | Блокировка пользователя с сообщением |
| `WebJobsShowValidationError` | Отображение ошибок проверки |
| `WebJobsModifyAttributeValues` | Изменение отправленных значений |
| `WebJobsOnOtpSendRequest` | Запрос события отправки OTP |
| `WebJobsOnOtpSendResponse` | Ответ события отправки OTP |
| `WebJobsOnOtpSendSuccess` | OTP успешно отправлен |
| `WebJobsOnOtpSendFailed` | Не удалось отправить OTP |
| `WebJobsContinueWithDefaultBehavior` | Продолжение со стандартным потоком |
Конфигурация Entra ID
После развертывания вашего приложения функций настройте пользовательское расширение в Entra ID:
- Зарегистрируйте API в Entra ID → Регистрация приложений
- Создайте пользовательское расширение аутентификации в Entra ID → Внешние идентификаторы → Пользовательские расширения аутентификации
- Свяжите с потоком пользователей в Entra ID → Внешние идентификаторы → Потоки пользователей
Требуемые настройки регистрации приложения
Открыть API:
- URI идентификатора приложения: api://<имя_вашего_приложения_функций>.azurewebsites.net
- Область: CustomAuthenticationExtension.Receive.Payload
Разрешения API:
- Microsoft Graph: User.Read (делегированные)
</your-function-app-name>Рекомендуемые практики
- Проверяйте все входные данные — Никогда не доверяйте данным запроса; проверяйте их перед обработкой
- Обработка ошибок должна быть корректной — Возвращайте соответствующие ответы об ошибках
- Логируйте идентификаторы корреляции — Используйте
CorrelationIdдля устранения неполадок - Держите функции быстрыми — У событий аутентификации есть ограничения по времени ожидания
- Используйте управляемую идентификацию — Безопасный доступ к ресурсам Azure
- Кэшируйте внешние данные — Избегайте меденных запросов при каждом обращении
- Тестируйте локально — Используйте инструменты ядра Azure Functions с примерами полезной нагрузки
- Мониторинг с помощью App Insights — Отслеживайте выполнение функций и ошибки
Обработка ошибок
[FunctionName("OnTokenIssuanceStart")]
public static WebJobsAuthenticationEventResponse Run(
[WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request,
ILogger log)
{
try
{
// Ваша логика здесь
var response = new WebJobsTokenIssuanceStartResponse();
response.Actions.Add(new WebJobsProvideClaimsForToken
{
Claims = new Dictionary<string> { { "claim", "value" } }
});
return response;
}
catch (Exception ex)
{
log.LogError(ex, "Ошибка при обработке события выдачи токена");
// Возврат пустого ответа — аутентификация продолжается без пользовательских утверждений
// НЕ выбрасывать исключение — это приведет к сбою аутентификации
return new WebJobsTokenIssuanceStartResponse();
}
}
</string>Связанные SDK
| SDK | Назначение | Установка |
|---|---|---|
| `Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents` | События аутентификации (этот SDK) | `dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents` |
| `Microsoft.Identity.Web` | Аутентификация веб-приложений | `dotnet add package Microsoft.Identity.Web` |
| `Azure.Identity` | Аутентификация Azure | `dotnet add package Azure.Identity` |
Ссылки на справочные материалы
| Ресурс | URL |
|---|---|
| Пакет NuGet | https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents |
| Обзор пользовательских расширений | https://learn.microsoft.com/entra/identity-platform/custom-extension-overview |
| События выдачи токена | https://learn.microsoft.com/entra/identity-platform/custom-extension-tokenissuancestart-setup |
| События сбора атрибутов | https://learn.microsoft.com/entra/identity-platform/custom-extension-attribute-collection |
| Исходный код на GitHub | 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 |
Все файлы
1 файловУстановить microsoft-azure-webjobs-extensions-authentication-events-dot
Скачайте и извлеките файлы навыков в директорию .claude/skills/.
Скачать ZIPКлонируйте репозиторий и скопируйте файлы навыка в свой проект.
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
Копировать





Дом
