Dela via


Konfigurera en anpassad e-postprovider för engångslösenord för att skicka händelser (förhandsversion)

Gäller för:Vit cirkel med en grå X-symbol.Personalklientorganisationer Grön cirkel med en vit bockmarkeringssymbol. Externa klienter (läs mer)

Den här artikeln innehåller en guide om hur du konfigurerar och konfigurerar en anpassad e-postprovider för händelsetypen Engångslösenord (OTP). Händelsen utlöses när ett OTP-e-postmeddelande aktiveras. Du kan anropa ett REST API för att använda din egen e-postleverantör genom att anropa ett REST API.

Dricks

Prova nu

Om du vill prova den här funktionen går du till woodgrove groceries-demonstrationen och startar användningsfallet "Använd en anpassad e-postprovider för engångskod".

Förutsättningar

Steg 1: Skapa en Azure-funktionsapp

Det här avsnittet visar hur du konfigurerar en Azure-funktionsapp i Azure Portal. Funktions-API:et är gatewayen till din e-postleverantör. Du skapar en Azure-funktionsapp som värd för FUNKTIONEN HTTP-utlösare och konfigurerar inställningarna i funktionen.

Dricks

Stegen i den här artikeln kan variera något beroende på vilken portal du börjar från.

  1. Logga in på Azure Portal som minst programadministratöroch autentiseringsadministratör.

  2. I menyn i Azure-portalen eller på sidan Start väljer du Skapa en resurs.

  3. Sök efter och välj Funktionsapp och välj Skapa.

  4. På sidan Skapa funktionsapp väljer du Förbrukning och sedan Välj.

  5. På sidan Skapa funktionsapp (förbrukning)fliken Grundläggande skapar du en funktionsapp med inställningarna som anges i följande tabell:

    Inställning Föreslaget värde beskrivning
    Abonnemang Din prenumeration Prenumerationen under vilken den nya funktionsappen skapas.
    Resursgrupp myResourceGroup Välj den resursgrupp som används för att konfigurera azure communications service - och e-postkommunikationstjänstens resurser som en del av förutsättningarna
    Funktionsappens namn Globalt unikt namn Ett namn som identifierar den nya funktionsappen. Giltiga tecken är a-z (skiftlägesokänsligt), 0-9 och -.
    Distribuera kod eller containeravbildning Kod Alternativ för att publicera kodfiler eller en Docker-container. I den här självstudien väljer du Kod.
    Körningsstack .NET Önskat programmeringsspråk. I den här självstudien väljer du .NET.
    Version: 8 (LTS) i processen Version av .NET-körningen. Processen innebär att du kan skapa och ändra funktioner i portalen, vilket rekommenderas för den här guiden
    Region Önskad region Välj en region som är nära dig eller nära andra tjänster som dina funktioner kan komma åt.
    Operativsystem Windows Operativsystemet är förvalt baserat på valet av körningsstack.
  6. Välj Granska + skapa för att granska appkonfigurationsvalen och välj sedan Skapa. Distributionen tar några minuter.

  7. När du har distribuerat väljer du Gå till resurs för att visa din nya funktionsapp.

1.1 Skapa en HTTP-utlösarfunktion

När Azure-funktionsappen har skapats skapar du en HTTP-utlösarfunktion. Med HTTP-utlösaren kan du anropa en funktion med en HTTP-begäran. Den här HTTP-utlösaren refereras av ditt anpassade Microsoft Entra-autentiseringstillägg.

  1. I funktionsappen går du till menyn och väljer Funktioner.
  2. Välj Skapa funktion.
  3. I fönstret Skapa funktion under Välj en mall söker du efter och väljer mallen HTTP-utlösare . Välj Nästa.
  4. Under Mallinformation anger du CustomAuthenticationExtensionsAPI för egenskapen Funktionsnamn .
  5. För auktoriseringsnivån väljer du Funktion.
  6. Välj Skapa.

1.2 Redigera funktionen

Koden börjar med att läsa det inkommande JSON-objektet. Microsoft Entra-ID skickar JSON-objektet till ditt API. I det här exemplet står det e-postadressen (identifieraren) och OTP. Sedan skickar koden informationen till kommunikationstjänsten för att skicka e-postmeddelandet med hjälp av en dynamisk mall.

Den här guiden visar otp-sändningshändelsen med Hjälp av Azure Communication Services och SendGrid. Använd flikarna för att välja din implementering.

  1. På menyn väljer du Kod + Test.

  2. Ersätt hela koden med följande kodfragment.

    using System.Dynamic;
    using System.Text.Json;
    using System.Text.Json.Nodes;
    using System.Text.Json.Serialization;
    using Azure.Communication.Email;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.HttpResults;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;
    
    namespace Company.AuthEvents.OnOtpSend.CustomEmailACS
    {
        public class CustomEmailACS
        {
            private readonly ILogger<CustomEmailACS> _logger;
    
            public CustomEmailACS(ILogger<CustomEmailACS> logger)
            {
                _logger = logger;
            }
    
            [Function("OnOtpSend_CustomEmailACS")]
            public async Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequest req)
            {
                _logger.LogInformation("C# HTTP trigger function processed a request.");
    
                // Get the request body
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                JsonNode jsonPayload = JsonNode.Parse(requestBody)!;
    
                // Get OTP and mail to
                string emailTo = jsonPayload["data"]!["otpContext"]!["identifier"]!.ToString();
                string otp = jsonPayload["data"]!["otpContext"]!["onetimecode"]!.ToString();
    
                // Send email
                await SendEmailAsync(emailTo, otp);
    
                // Prepare response
                ResponseObject responseData = new ResponseObject("microsoft.graph.OnOtpSendResponseData");
                responseData.Data.Actions = new List<ResponseAction>() { new ResponseAction(
                    "microsoft.graph.OtpSend.continueWithDefaultBehavior") };
    
                return new OkObjectResult(responseData);
            }
    
            private async Task SendEmailAsync(string emailTo, string code)
            {
                // Get app settings
                var connectionString = Environment.GetEnvironmentVariable("mail_connectionString");
                var sender = Environment.GetEnvironmentVariable("mail_sender");
                var subject = Environment.GetEnvironmentVariable("mail_subject");
    
                try
                {
                    if (!string.IsNullOrEmpty(connectionString))
                    {
                        var emailClient = new EmailClient(connectionString);
                        var body = EmailTemplate.GenerateBody(code);
    
                        _logger.LogInformation($"Sending OTP to {emailTo}");
    
                        EmailSendOperation emailSendOperation = await emailClient.SendAsync(
                        Azure.WaitUntil.Started,
                        sender,
                        emailTo,
                        subject,
                        body);
                    }
                }
                catch (System.Exception ex)
                {
                    _logger.LogError(ex.Message);
                }
            }
        }
    
        public class ResponseObject
        {
            [JsonPropertyName("data")]
            public Data Data { get; set; }
    
            public ResponseObject(string dataType)
            {
                Data = new Data(dataType);
            }
        }
    
        public class Data
        {
            [JsonPropertyName("@odata.type")]
            public string DataType { get; set; }
            [JsonPropertyName("actions")]
            public List<ResponseAction> Actions { get; set; }
    
            public Data(string dataType)
            {
                DataType = dataType;
            }
        }
    
        public class ResponseAction
        {
            [JsonPropertyName("@odata.type")]
            public string DataType { get; set; }
    
            public ResponseAction(string dataType)
            {
                DataType = dataType;
            }
        }
    
        public class EmailTemplate
        {
            public static string GenerateBody(string oneTimeCode)
            {
                return @$"<html><body>
                <div style='background-color: #1F6402!important; padding: 15px'>
                    <table>
                    <tbody>
                        <tr>
                            <td colspan='2' style='padding: 0px;font-family: "Segoe UI Semibold", "Segoe UI Bold", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif;font-size: 17px;color: white;'>Woodgrove Groceries live demo</td>
                        </tr>
                        <tr>
                            <td colspan='2' style='padding: 15px 0px 0px;font-family: "Segoe UI Light", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif;font-size: 35px;color: white;'>Your Woodgrove verification code</td>
                        </tr>
                        <tr>
                            <td colspan='2' style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'> To access <span style='font-family: "Segoe UI Bold", "Segoe UI Semibold", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif; font-size: 14px; font-weight: bold; color: white;'>Woodgrove Groceries</span>'s app, please copy and enter the code below into the sign-up or sign-in page. This code is valid for 30 minutes. </td>
                        </tr>
                        <tr>
                            <td colspan='2' style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'>Your account verification code:</td>
                        </tr>
                        <tr>
                            <td style='padding: 0px;font-family: "Segoe UI Bold", "Segoe UI Semibold", "Segoe UI", "Helvetica Neue Medium", Arial, sans-serif;font-size: 25px;font-weight: bold;color: white;padding-top: 5px;'>
                            {oneTimeCode}</td>
                            <td rowspan='3' style='text-align: center;'>
                                <img src='https://woodgrovedemo.com/custom-email/shopping.png' style='border-radius: 50%; width: 100px'>
                            </td>
                        </tr>
                        <tr>
                            <td style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'> If you didn't request a code, you can ignore this email. </td>
                        </tr>
                        <tr>
                            <td style='padding: 25px 0px 0px;font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white;'> Best regards, </td>
                        </tr>
                        <tr>
                            <td>
                                <img src='https://woodgrovedemo.com/Company-branding/headerlogo.png' height='20'>
                            </td>
                            <td style='font-family: "Segoe UI", Tahoma, Verdana, Arial, sans-serif;font-size: 14px;color: white; text-align: center;'>
                                <a href='https://woodgrovedemo.com/Privacy' style='color: white; text-decoration: none;'>Privacy Statement</a>
                            </td>
                        </tr>
                    </tbody>
                    </table>
                </div>
                </body></html>";
            }
        }
    }
    
  3. Välj Hämta funktions-URL och kopiera url:en för funktionsnyckeln, som hädanefter används och kallas .{Function_Url} Stäng funktionen.

Steg 2: Lägg till anslutningssträng i Azure-funktionen

Anslutningssträngar gör det möjligt för Communication Services SDK:er att ansluta och autentisera till Azure. För både Azure Communication Services och SendGrid måste du lägga till dessa anslutningssträng i Azure-funktionsappen som miljövariabler.

2.1: Extrahera anslutningssträng och tjänstslutpunkter från din Azure Communication Services-resurs

Du kan komma åt dina Communication Services-anslutningssträng och tjänstslutpunkter från Azure Portal eller programmatiskt med Azure Resource Manager-API:er.

  1. På sidan Start i Azure Portal öppnar du portalmenyn, söker efter och väljer Alla resurser.

  2. Sök efter och välj den Azure Communications Service som skapats som en del av förutsättningarna för den här artikeln.

  3. Välj listrutan Inställningar i den vänstra rutan och välj sedan Nycklar.

  4. Kopiera slutpunkten och kopiera värdena för nyckel- och anslutningssträngen från primärnyckeln.

    Skärmbild av sidan Azure Communications Service Keys som visar slutpunkten och nyckelplatserna.

2.2: Lägg till anslutningssträng i Azure-funktionen

  1. Gå tillbaka till den Azure-funktion som du skapade i Skapa en Azure-funktionsapp.

  2. sidan Översikt i funktionsappen går du till den vänstra menyn och väljer Inställningar>Miljövariabler lägger till följande appinställningar. När alla inställningar har lagts till väljer du Använd och sedan Bekräfta.

    Inställning Värde (exempel) beskrivning
    mail_connectionString https://ciamotpcommsrvc.unitedstates.communication.azure.com/:accesskey=A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u Slutpunkt för Azure Communication Services
    mail_sender from.email@myemailprovider.com Från e-postadressen.
    mail_subject CIAM-demo Ämnet för e-postmeddelandet.

Steg 3: Registrera ett anpassat autentiseringstillägg

I det här steget konfigurerar du ett anpassat autentiseringstillägg som Microsoft Entra-ID använder för att anropa din Azure-funktion. Det anpassade autentiseringstillägget innehåller information om rest-API-slutpunkten, de anspråk som det parsar från rest-API:et och hur du autentiserar till rest-API:et. Använd antingen Azure Portal eller Microsoft Graph för att registrera ett program för att autentisera ditt anpassade autentiseringstillägg till din Azure-funktion.

Registrera ett anpassat autentiseringstillägg

  1. Logga in på Azure Portal som minst programadministratöroch autentiseringsadministratör.

  2. Sök efter och välj Microsoft Entra-ID och välj Företagsprogram.

  3. Välj Anpassade autentiseringstillägg och välj sedan Skapa ett anpassat tillägg.

  4. I Grundläggande väljer du händelsetypen EmailOtpSend och väljer Nästa.

    Skärmbild av Azure Portal som markerar otp-sändningshändelsen för e-post.

  5. På fliken Slutpunktskonfiguration fyller du i följande egenskaper och väljer sedan Nästa för att fortsätta.

    • Namn – Ett namn på ditt anpassade autentiseringstillägg. Till exempel Skicka otp-e-post.
    • Mål-URL – Url:en för {Function_Url} din Azure-funktion. Gå till sidan Översikt för azure-funktionsappen och välj sedan den funktion som du skapade. På funktionsöversiktssidan väljer du Hämta funktions-URL och använder kopieringsikonen för att kopiera url:en för customauthenticationextension_extension (systemnyckel).
    • Beskrivning – En beskrivning av dina anpassade autentiseringstillägg.
  6. På fliken API-autentisering väljer du alternativet Skapa ny appregistrering för att skapa en appregistrering som representerar din funktionsapp.

  7. Ge appen ett namn, till exempel API för Azure Functions-autentiseringshändelser, och välj Nästa.

  8. På fliken Program väljer du det program som ska associeras med det anpassade autentiseringstillägget. Välj Nästa. Du har möjlighet att tillämpa den i hela klientorganisationen genom att markera kryssrutan. Klicka på Nästa när du vill fortsätta.

  9. På fliken Granska kontrollerar du att informationen är korrekt för det anpassade autentiseringstillägget. Observera app-ID :t under API-autentisering, som behövs för att konfigurera autentisering för din Azure-funktion i azure-funktionsappen. Välj Skapa.

När ditt anpassade autentiseringstillägg har skapats öppnar du programmet från portalen under Appregistreringar och väljer API-behörigheter.

På sidan API-behörigheter väljer du knappen Bevilja administratörsmedgivande för "YourTenant" för att ge administratörsmedgivande till den registrerade appen, vilket gör att det anpassade autentiseringstillägget kan autentisera till ditt API. Det anpassade autentiseringstillägget använder client_credentials för att autentisera till Azure-funktionsappen med hjälp av behörigheten Receive custom authentication extension HTTP requests .

Följande skärmbild visar hur du beviljar behörigheter.

Skärmbild av Azure Portal och hur du beviljar administratörsmedgivande.

Steg 4: Konfigurera en OpenID Connect-app att testa med

Om du vill hämta en token och testa tillägget för anpassad autentisering kan du använda https://jwt.ms appen. Det är ett Microsoft-ägt webbprogram som visar det avkodade innehållet i en token (innehållet i token lämnar aldrig webbläsaren).

Följ dessa steg för att registrera jwt.ms webbappen:

4.1 Registrera ett testwebbprogram

  1. Logga in på administrationscentret för Microsoft Entra som minst programadministratör.
  2. Bläddra till Programregistreringar för identitetsprogram>
  3. Välj Ny registrering.
  4. Ange ett namn för programmet. Till exempel Mitt testprogram.
  5. Under Kontotyper som stöds väljer du Endast Konton i den här organisationskatalogen.
  6. I listrutan Välj en plattform i Omdirigerings-URI väljer du Webb och anger https://jwt.ms sedan i textrutan URL.
  7. Välj Registrera för att slutföra appregistreringen.
  8. I appregistreringen, under Översikt, kopierar du program-ID:t (klient-ID: t), som används senare och kallas för {App_to_sendotp_ID}. I Microsoft Graph refereras den av egenskapen appId .

Följande skärmbild visar hur du registrerar programmet Mitt test.

Skärmbild som visar hur du väljer den kontotyp som stöds och omdirigerings-URI.

4.1 Hämta program-ID

I din appregistrering, under Översikt, kopierar du program-ID:t (klient). App-ID:t kallas {App_to_sendotp_ID} i senare steg. I Microsoft Graph refereras den av egenskapen appId .

4.2 Aktivera implicit flöde

Det jwt.ms testprogrammet använder det implicita flödet. Aktivera implicit flöde i registrering av mitt testprogram :

  1. Under Hantera väljer du Autentisering.
  2. Under Implicit beviljande och hybridflöden markerar du kryssrutan ID-token (används för implicita flöden och hybridflöden).
  3. Välj Spara.

Kommentar

Den jwt.ms appen använder det implicita flödet för att hämta en ID-token och är endast i testsyfte. Det implicita flödet rekommenderas inte för produktionsprogram. För produktionsprogram använder du auktoriseringskodflödet.

Steg 5: Skydda din Azure-funktion

Microsoft Entra-tillägget för anpassad autentisering använder server-till-server-flöde för att hämta en åtkomsttoken som skickas i HTTP-huvudet till din Azure-funktion Authorization . När du publicerar din funktion till Azure, särskilt i en produktionsmiljö, måste du verifiera token som skickas i auktoriseringshuvudet.

Om du vill skydda din Azure-funktion följer du de här stegen för att integrera Microsoft Entra-autentisering för att verifiera inkommande token med din Api-programregistrering för Azure Functions-autentiseringshändelser.

Kommentar

Om Azure-funktionsappen finns i en annan Azure-klientorganisation än den klient där ditt anpassade autentiseringstillägg är registrerat går du vidare till steget OpenID Connect-identitetsprovider .

  1. Logga in på Azure-portalen.
  2. Navigera och välj den funktionsapp som du publicerade tidigare.
  3. Välj Autentisering i menyn till vänster.
  4. Välj Lägg till identitetsprovider.
  5. I listrutanVälj Microsoft som identitetsprovider.
  6. Under Appregistrerings-Appregistreringstyp väljer du > och väljer api-appregistreringenför Azure Functions-autentiseringshändelser som du skapade tidigare när du registrerade den anpassade e-postleverantören.
  7. Lägg till förfallodatum för klienthemlighet för appen.
  8. Under Oautentiserade begäranden väljer du HTTP 401 Obehörig som identitetsprovider.
  9. Avmarkera alternativet Tokenlagring .
  10. Välj Lägg till för att lägga till autentisering i din Azure-funktion.

Skärmbild som visar hur du lägger till autentisering i funktionsappen.

5.1 Använda OpenID Connect-identitetsprovider

Om du har konfigurerat Microsofts identitetsprovider hoppar du över det här steget. Om Azure-funktionen annars finns i en annan klientorganisation än klientorganisationen där ditt anpassade autentiseringstillägg är registrerat följer du dessa steg för att skydda din funktion:

  1. Logga in på Azure Portal, navigera och välj sedan den funktionsapp som du tidigare publicerade.

  2. Välj Autentisering i det vänstra fönstret.

  3. Välj Lägg till identitetsprovider.

  4. Välj OpenID Connect som identitetsprovider.

  5. Ange ett namn, till exempel Contoso Microsoft Entra-ID.

  6. Under posten Metadata anger du följande URL till dokument-URL:en. {tenantId} Ersätt med ditt Klient-ID för Microsoft Entra och {tenantname} med namnet på din klientorganisation utan "onmicrosoft.com".

    https://{tenantname}.ciamlogin.com/{tenantId}/v2.0/.well-known/openid-configuration
    
  7. Under Appregistrering anger du program-ID (klient-ID) för api-appregistreringen för Azure Functions-autentiseringshändelser som du skapade tidigare.

  8. I administrationscentret för Microsoft Entra:

    1. Välj api-appregistreringen för Azure Functions-autentiseringshändelser som du skapade tidigare.
    2. Välj >>Ny klienthemlighet.
    3. Lägg till en beskrivning för din klienthemlighet.
    4. Välj en förfallotidpunkt för hemligheten eller ange en anpassad livslängd.
    5. Markera Lägga till.
    6. Registrera hemlighetens värde för användning i klientprogramkoden. Hemlighetens värde visas aldrig igen när du har lämnat den här sidan.
  9. Gå tillbaka till Azure-funktionen under Appregistreringen och ange klienthemligheten.

  10. Avmarkera alternativet Tokenlagring .

  11. Välj Lägg till för att lägga till OpenID Connect-identitetsprovidern.

Steg 6: Testa programmet

Följ dessa steg för att testa din anpassade e-postprovider:

  1. Öppna en ny privat webbläsare och navigera och logga in via följande URL.

    https://{tenantname}.ciamlogin.com/{tenant-id}/oauth2/v2.0/authorize?client_id={App_to_sendotp_ID}&response_type=id_token&redirect_uri=https://jwt.ms&scope=openid&state=12345&nonce=12345
    
  2. Ersätt {tenant-id} med ditt klientorganisations-ID, klientnamn eller något av dina verifierade domännamn. Exempel: contoso.onmicrosoft.com

  3. Ersätt {tenantname} med namnet på klientorganisationen utan "onmicrosoft.com".

  4. Ersätt {App_to_sendotp_ID} med registrerings-ID för mitt testprogram.

  5. Se till att du loggar in med ett e-postlösenordskonto för engångslösenord. Välj sedan Skicka kod. Se till att koden som skickas till de registrerade e-postadresserna använder den anpassade providern som registrerats ovan.

Steg 7: Gå tillbaka till Microsoft-providern

Om ett fel inträffar i ditt tilläggs-API skickar inte Etttra-ID som standard en OTP till användaren. Du kan i stället ange att felbeteendet ska återgå till Microsoft-providern.

Om du vill aktivera detta kör du följande begäran. Ersätt {customListenerOjectId} med det anpassade autentiseringslyssnings-ID som registrerats tidigare.

  • Du behöver behörigheten EventListener.ReadWrite.All delegated.
PATCH https://graph.microsoft.com/beta/identity/authenticationEventListeners/{customListenerOjectId}

{
    "@odata.type": "#microsoft.graph.onEmailOtpSendListener",
    "handler": {
        "@odata.type": "#microsoft.graph.onOtpSendCustomExtensionHandler",
        "configuration": {
            "behaviorOnError": {
                "@odata.type": "#microsoft.graph.fallbackToMicrosoftProviderOnError"
            }
        }
    }
}

Se även