본문으로 건너뛰기
cccskills
Microsoft 공식무료GitHub에 공개

microsoft-azure-webjobs-extensions-authentication-events-dotnet

Implement Microsoft Entra ID authentication extensions with .NET and Azure Functions. Add custom claims, or user information, to tokens, customize sign-up fields, validate submitted attributes, and connect one-time password delivery to a chosen messaging provider.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Microsoft Entra Authentication Events SDK for .NET. Azure Functions triggers for custom authentication extensions. Use for token enrichment, custom claims, attribute collection, and OTP customization in Entra ID. Triggers: "Authentication Events", "WebJobsAuthenticationEventsTrigger", "OnTokenIssuanceStart", "OnAttributeCollectionStart", "custom claims", "token enrichment", "Entra custom extension", "authentication extension".

연동 도구Azure
설치 방법 보기

이럴 때 유용합니다

  • Adding department or employee details to sign-in tokens
  • Prefilling fields on sign-up forms
  • Validating and correcting submitted registration details
  • Sending one-time passwords through a custom provider

포함된 파일(1)

  • SKILL.md14.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents (.NET)

Azure Functions extension for handling Microsoft Entra ID custom authentication events.

Installation

dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents

Current Version: v1.1.0 (stable)

Supported Events

EventPurpose
OnTokenIssuanceStartAdd custom claims to tokens during issuance
OnAttributeCollectionStartCustomize attribute collection UI before display
OnAttributeCollectionSubmitValidate/modify attributes after user submission
OnOtpSendCustom OTP delivery (SMS, email, etc.)

Core Workflows

1. Token Enrichment (Add Custom Claims)

Add custom claims to access or ID tokens during sign-in.

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).

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.

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.

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).

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.

// Program.cs (Isolated worker model)
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"
  }
}

Key Types Reference

TypePurpose
WebJobsAuthenticationEventsTriggerAttributeFunction trigger attribute
WebJobsTokenIssuanceStartRequestToken issuance event request
WebJobsTokenIssuanceStartResponseToken issuance event response
WebJobsProvideClaimsForTokenAction to add claims
WebJobsAttributeCollectionStartRequestAttribute collection start request
WebJobsAttributeCollectionStartResponseAttribute collection start response
WebJobsAttributeCollectionSubmitRequestAttribute submission request
WebJobsAttributeCollectionSubmitResponseAttribute submission response
WebJobsSetPrefillValuesPrefill form values
WebJobsShowBlockPageBlock user with message
WebJobsShowValidationErrorShow validation errors
WebJobsModifyAttributeValuesModify submitted values
WebJobsOnOtpSendRequestOTP send event request
WebJobsOnOtpSendResponseOTP send event response
WebJobsOnOtpSendSuccessOTP sent successfully
WebJobsOnOtpSendFailedOTP send failed
WebJobsContinueWithDefaultBehaviorContinue 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

[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

SDKPurposeInstall
Microsoft.Azure.WebJobs.Extensions.AuthenticationEventsAuth events (this SDK)dotnet add package Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents
Microsoft.Identity.WebWeb app authenticationdotnet add package Microsoft.Identity.Web
Azure.IdentityAzure authenticationdotnet add package Azure.Identity

Reference Links

ResourceURL
NuGet Packagehttps://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents
Custom Extensions Overviewhttps://learn.microsoft.com/entra/identity-platform/custom-extension-overview
Token Issuance Eventshttps://learn.microsoft.com/entra/identity-platform/custom-extension-tokenissuancestart-setup
Attribute Collection Eventshttps://learn.microsoft.com/entra/identity-platform/custom-extension-attribute-collection
GitHub Sourcehttps://github.com/Azure/azure-sdk-for-net/tree/main/sdk/entra/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

agent-framework-azure-ai-py

Microsoft 공식무료

Create Python agents on Azure AI Foundry that retain conversation context and use multiple tools. The skill covers code execution, file and web search, external tool connections, streaming responses, and outputs organized into defined fields.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Build an agent that retains conversation context
  • Combine code execution with file and web search
  • Connect external tools through MCP
microsoft/skills3.1천2026년 10월 23일 업데이트

airunway-aks-setup

Microsoft 공식무료

Set up AI Runway on an existing AKS cluster, from checking cluster health and GPU compatibility to installing model serving software, deploying a first AI model, and verifying that it runs.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Setting up AI Runway on an existing AKS cluster
  • Checking GPU compatibility before deploying a model
  • Choosing and installing model serving software
microsoft/skills3.1천2026년 10월 23일 업데이트

aks-gpu-inference

Microsoft 공식무료

Investigate GPU and KAITO failures in AKS using read-only evidence. Helps distinguish scheduling problems, memory shortages, workspace readiness issues, and scaling failures, then organizes findings with confidence levels and missing evidence.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Investigating GPU pods stuck in Pending
  • Distinguishing container memory shortages from GPU memory failures
  • Investigating a KAITO Workspace that is not ready
microsoft/skills3.1천2026년 10월 23일 업데이트

aks-known-issues

Microsoft 공식무료

Find documented fixes for known AKS errors by matching the exact error message and required conditions. Get an explanation of the cause, a proposed fix, a Microsoft Learn reference, and read-only verification steps.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Look up a documented fix for a specific AKS error
  • Check the cause of a node pool creation failure
  • Review verification steps before changing AKS resources
microsoft/skills3.1천2026년 10월 23일 업데이트

aks-network-capture

Microsoft 공식무료

Collect bounded packet captures from AKS nodes or pods alongside Azure network settings. Use the captured traffic as evidence when investigating where packets are lost, after initial checks that do not change the environment.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Collect packet captures from an AKS node
  • Gather evidence of where packets are lost
  • Retrieve captures alongside Azure network settings
microsoft/skills3.1천2026년 10월 23일 업데이트

aks-troubleshooting

Microsoft 공식무료

Investigate live Azure Kubernetes Service incidents through read-only checks of logs, events, and resource state. Trace workload, node, networking, or upgrade failures and produce an incident report with supporting evidence, confidence, and proposed remediation.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Investigating crashing or Pending pods
  • Tracing DNS, ingress, and connectivity failures
  • Diagnosing node-pool scaling and quota failures
microsoft/skills3.1천2026년 10월 23일 업데이트

microsoft의 스킬 모두 보기

이 스킬의 문제 신고