Självstudier: Azure SignalR Service-autentisering med Azure Functions

I den här stegvisa självstudien skapar du ett chattrum med autentisering och privata meddelanden med hjälp av följande tekniker:

Kommentar

Du kan hämta koden som nämns i den här artikeln från GitHub.

Förutsättningar

Har du problem? Berätta för oss.

Skapa viktiga resurser i Azure

Skapa en Azure SignalR Service-resurs

Ditt program får åtkomst till en Azure SignalR Service-instans. Använd följande steg för att skapa en Azure SignalR Service-instans med hjälp av Azure-portalen:

  1. I Azure-portalen väljer du knappen Skapa en resurs (+).

  2. Sök efter och välj SignalR Service.

  3. Välj Skapa.

  4. Ange följande information.

    Name Värde
    Resursgrupp Skapa en ny resursgrupp med ett unikt namn.
    Resursnamn Ange ett unikt namn för Azure SignalR Service-instansen.
    Region Välj en region nära dig.
    Prisnivå Välj Kostnadsfri.
    Tjänstläge Välj Serverlös.
  5. Välj Granska + skapa.

  6. Välj Skapa.

Har du problem? Berätta för oss.

Skapa en Azure-funktionsapp och ett Azure Storage-konto

  1. På startsidan i Azure-portalen väljer du Skapa en resurs (+).

  2. Sök efter funktionsapp och välj den.

  3. Välj Skapa.

  4. Ange följande information.

    Name Värde
    Resursgrupp Använd samma resursgrupp med din Azure SignalR Service-instans.
    Funktionsappens namn Ange ett unikt namn för funktionsappen.
    Körningsstack Välj Node.js.
    Region Välj en region nära dig.
  5. Som standard skapas ett nytt Azure-lagringskonto i samma resursgrupp tillsammans med din funktionsapp. Om du vill använda ett annat lagringskonto i funktionsappen växlar du till fliken Värd för att välja ett konto.

  6. Välj Granska + skapaoch välj sedan Skapa.

Skapa ett Azure Functions-projekt lokalt

Initiera en funktionsapp

  1. Från en kommandorad skapar du en rotmapp för projektet och ändrar till mappen.

  2. Kör följande kommando i terminalen för att skapa ett nytt JavaScript Functions-projekt:

func init --worker-runtime node --language javascript --name my-app --model V4

Som standard innehåller det genererade projektet en host.json fil som innehåller tilläggspaketen som innehåller SignalR-tillägget. Mer information om tilläggspaket finns i Registrera Azure Functions-bindningstillägg.

Konfigurera programinställningar

När du kör och felsöker Azure Functions-körningen lokalt läser funktionsappen programinställningar från local.settings.json. Uppdatera den här filen med niska veze för Azure SignalR Service-instansen och lagringskontot som du skapade tidigare.

Ersätt innehållet i local.settings.json med följande kod:

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "<your-storage-account-connection-string>",
    "AzureSignalRConnectionString": "<your-Azure-SignalR-connection-string>"
  }
}

I koden ovan:

  • Ange Azure SignalR Service-niska veze i inställningenAzureSignalRConnectionString.

    Om du vill hämta strängen går du till din Azure SignalR Service-instans i Azure-portalen. Leta upp inställningen Nycklar i avsnittet Inställningar. Välj knappen Kopiera till höger om niska veze för att kopiera den till Urklipp. Du kan använda antingen den primära eller sekundära niska veze.

  • Ange lagringskontot niska veze i inställningenAzureWebJobsStorage.

    Hämta strängen genom att gå till ditt lagringskonto i Azure-portalen. Leta upp inställningen Åtkomstnycklar i avsnittet Säkerhet + nätverk. Välj knappen Kopiera till höger om niska veze för att kopiera den till Urklipp. Du kan använda antingen den primära eller sekundära niska veze.

Har du problem? Berätta för oss.

Skapa en funktion för att autentisera användare till Azure SignalR Service

När chattappen öppnas i webbläsaren krävs giltiga autentiseringsuppgifter för att ansluta till Azure SignalR Service. Skapa en HTTP-utlösarfunktion med namnet negotiate i funktionsappen för att returnera den här anslutningsinformationen.

Kommentar

Den här funktionen måste namnges negotiate eftersom SignalR-klienten kräver en slutpunkt som slutar i /negotiate.

  1. Från rotprojektmappen negotiate skapar du funktionen från en inbyggd mall med hjälp av följande kommando:

    func new --template "HTTP trigger" --name negotiate
    
  2. Öppna src/functions/negotiate.js, uppdatera innehållet på följande sätt:

    const { app, input } = require('@azure/functions');
    
    const inputSignalR = input.generic({
        type: 'signalRConnectionInfo',
        name: 'connectionInfo',
        hubName: 'default',
        connectionStringSetting: 'AzureSignalRConnectionString',
    });
    
    app.post('negotiate', {
        authLevel: 'anonymous',
        handler: (request, context) => {
            return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
        },
        route: 'negotiate',
        extraInputs: [inputSignalR],
    });
    

    Funktionen innehåller en HTTP-utlösarbindning för att ta emot begäranden från SignalR-klienter. Funktionen innehåller också en SignalR-indatabindning för att generera giltiga autentiseringsuppgifter för en klient för att ansluta till en Azure SignalR Service-hubb med namnet default.

    Den här funktionen tar SignalR-anslutningsinformationen från indatabindningen och returnerar den till klienten i HTTP-svarstexten..

    Det finns ingen userId egenskap i bindningen signalRConnectionInfo för lokal utveckling. Du lägger till den senare för att ange användarnamnet för en SignalR-anslutning när du distribuerar funktionsappen till Azure.

Har du problem? Berätta för oss.

Skapa en funktion för att skicka chattmeddelanden

Webbappen kräver också ett HTTP-API för att skicka chattmeddelanden. Skapa en HTTP-utlösarfunktion som skickar meddelanden till alla anslutna klienter som använder Azure SignalR Service:

  1. Från rotprojektmappen skapar du en HTTP-utlösarfunktion med namnet sendMessage från mallen med hjälp av följande kommando:

    func new --name sendMessage --template "Http trigger"
    
  2. Öppna filen src/functions/sendMessage.js och uppdatera innehållet på följande sätt:

    const { app, output } = require('@azure/functions');
    
    const signalR = output.generic({
        type: 'signalR',
        name: 'signalR',
        hubName: 'default',
        connectionStringSetting: 'AzureSignalRConnectionString',
    });
    
    app.http('messages', {
        methods: ['POST'],
        authLevel: 'anonymous',
        extraOutputs: [signalR],
        handler: async (request, context) => {
            const message = await request.json();
            message.sender = request.headers && request.headers.get('x-ms-client-principal-name') || '';
    
            let recipientUserId = '';
            if (message.recipient) {
                recipientUserId = message.recipient;
                message.isPrivate = true;
            }
            context.extraOutputs.set(signalR,
                {
                    'userId': recipientUserId,
                    'target': 'newMessage',
                    'arguments': [message]
                });
        }
    });
    

    Funktionen innehåller en HTTP-utlösare och en SignalR-utdatabindning. Den tar brödtexten från HTTP-begäran och skickar den till klienter som är anslutna till Azure SignalR Service. Den anropar en funktion med namnet newMessage på varje klient.

    Funktionen kan läsa avsändarens identitet och kan acceptera ett recipient värde i meddelandetexten så att du kan skicka ett meddelande privat till en enskild användare. Du använder dessa funktioner senare i självstudien.

  3. Spara filen.

Har du problem? Berätta för oss.

Värd för chattklientens webbanvändargränssnitt

Chattprogrammets användargränssnitt är ett enkelt enkelsidigt program (SPA) som skapats med Vue JavaScript-ramverket med hjälp av ASP.NET Core SignalR JavaScript-klienten. För enkelhetens skull är funktionsappen värd för webbsidan. I en produktionsmiljö kan du använda Static Web Apps som värd för webbsidan.

  1. Skapa en fil med namnet index.html i rotkatalogen för funktionsprojektet.

  2. Kopiera och klistra in innehållet i index.html i filen. Spara filen.

  3. Från rotprojektmappen skapar du en HTTP-utlösarfunktion med namnet index från mallen med hjälp av det här kommandot:

    func new --name index --template "Http trigger"
    
  4. Ändra innehållet i src/functions/index.js till följande kod:

    const { app } = require('@azure/functions');
    const { readFile } = require('fs/promises');
    
    app.http('index', {
        methods: ['GET'],
        authLevel: 'anonymous',
        handler: async (context) => {
            const content = await readFile('index.html', 'utf8', (err, data) => {
                if (err) {
                    context.err(err)
                    return
                }
            });
    
            return {
                status: 200,
                headers: {
                    'Content-Type': 'text/html'
                },
                body: content,
            };
        }
    });
    

    Funktionen läser den statiska webbsidan och returnerar den till användaren.

  5. Testa appen lokalt. Starta funktionsappen med det här kommandot:

    func start
    
  6. Öppna http://localhost:7071/api/index i webbläsaren. En chattwebbsida bör visas.

    Skärmbild av ett webbanvändargränssnitt för en lokal chattklient.

  7. Ange ett meddelande i chattrutan.

    När du har valt returnyckeln visas meddelandet på webbsidan. Eftersom användarnamnet för SignalR-klienten inte har angetts skickar du alla meddelanden anonymt.

Har du problem? Berätta för oss.

Distribuera till Azure och aktivera autentisering

Du har kört funktionsappen och chattappen lokalt. Distribuera dem nu till Azure och aktivera autentisering och privata meddelanden.

Konfigurera funktionsappen för autentisering

Hittills fungerar chattappen anonymt. I Azure använder du App Service-autentisering för att autentisera användaren. Användar-ID:t eller användarnamnet för den autentiserade användaren skickas till bindningen SignalRConnectionInfo för att generera anslutningsinformation som autentiseras som användaren.

  1. Öppna filen src/functions/negotiate.js .

  2. Infoga en userId egenskap i bindningen inputSignalR med värdet {headers.x-ms-client-principal-name}. Det här värdet är ett bindningsuttryck som anger användarnamnet för SignalR-klienten till namnet på den autentiserade användaren. Bindningen bör nu se ut så här:

    const inputSignalR = input.generic({
        type: 'signalRConnectionInfo',
        name: 'connectionInfo',
        hubName: 'default',
        connectionStringSetting: 'AzureSignalRConnectionString',
        userId: '{headers.x-ms-client-principal-name}'
    });
    
  3. Spara filen.

Distribuera funktionsappen till Azure

Distribuera funktionsappen till Azure med hjälp av följande kommando:

func azure functionapp publish <your-function-app-name> --publish-local-settings

Alternativet --publish-local-settings publicerar dina lokala inställningar från local.settings.json-filen till Azure, så du behöver inte konfigurera dem i Azure igen.

Aktivera App Service-autentisering

Azure Functions stöder autentisering med Microsoft Entra-ID, Facebook, X, Microsoft-konto och Google. Du använder Microsoft som identitetsprovider för den här självstudien.

  1. I Azure-portalen går du till resurssidan för funktionsappen.

  2. Välj Inställningar>Autentisering.

  3. Välj Lägg till identitetsprovider.

    Skärmbild av funktionsappens autentiseringssida och knappen för att lägga till en identitetsprovider.

  4. I listan Identitetsprovider väljer du Microsoft. Välj Lägg till.

    Skärmbild av sidan för att lägga till en identitetsprovider.

De slutförda inställningarna skapar en appregistrering som associerar din identitetsprovider med din funktionsapp.

Mer information om identitetsprovidrar som stöds finns i följande artiklar:

Testa programmet

  1. Öppna https://<YOUR-FUNCTION-APP-NAME>.azurewebsites.net/api/index.
  2. Välj Logga in för att autentisera med din valda autentiseringsprovider.
  3. Skicka offentliga meddelanden genom att ange dem i huvudchattrutan.
  4. Skicka privata meddelanden genom att välja ett användarnamn i chatthistoriken. Endast den valda mottagaren tar emot dessa meddelanden.

Skärmbild av en autentiserad onlineklientchattapp.

Grattis! Du har distribuerat en serverlös chattapp i realtid.

Har du problem? Berätta för oss.

Rensa resurser

Om du vill rensa de resurser som du skapade i den här självstudien tar du bort resursgruppen med hjälp av Azure-portalen.

Varning

Om du tar bort resursgruppen tas alla resurser som den innehåller bort. Om resursgruppen innehåller resurser utanför omfånget för den här självstudien tas de också bort.

Har du problem? Berätta för oss.

Nästa steg

I den här självstudien har du lärt dig hur du använder Azure Functions med Azure SignalR Service. Läs mer om att skapa serverlösa program i realtid med Azure SignalR Service-bindningar för Azure Functions:

Har du problem? Berätta för oss.