Tutorial: Autenticação do Serviço Azure SignalR com o Azure Functions

Neste tutorial passo a passo, você cria uma sala de chat com autenticação e mensagens privadas usando estas tecnologias:

Observação

Obtenha o código mencionado neste artigo no GitHub.

Pré-requisitos

Está com problemas? Queremos saber.

Crie recursos essenciais no Azure

Crie um recurso de Serviço do Azure SignalR

Seu aplicativo acessará uma instância de Serviço do Azure SignalR. Use as seguintes etapas para criar uma instância do Serviço do Azure SignalR usando o portal do Azure:

  1. No portal do Azure, selecione o botão Criar um recurso (+).

  2. Pesquise Serviço SignalR e selecione-o.

  3. Selecione Criar.

  4. Insira as seguintes informações.

    Nome Valor
    Grupo de recursos Crie um novo grupo de recursos e dê a ele um nome exclusivo.
    Nome do recurso Insira um nome exclusivo para a instância do Serviço do Azure SignalR.
    Região Selecione uma região próxima a você.
    Tipo de preço Selecione Gratuito.
    Modo de serviço Selecione Sem servidor.
  5. Selecione Examinar + criar.

  6. Selecione Criar.

Está enfrentando problemas? Queremos saber.

Crie um aplicativo de funções do Azure e uma conta de Armazenamento do Microsoft Azure

  1. Na home page do portal do Azure, selecione Criar um recurso (+).

  2. Procure o Aplicativo de Funções e selecione-o.

  3. Selecione Criar.

  4. Insira as seguintes informações.

    Nome Valor
    Grupo de recursos Use o mesmo grupo de recursos com a instância do Serviço do Azure SignalR.
    Nome do aplicativo de funções Um nome exclusivo para a instância do aplicativo de funções.
    Pilha de runtime Selecione Node.js.
    Região Selecione uma região próxima a você.
  5. Por padrão, uma nova conta de Armazenamento do Microsoft Azure também é criada no mesmo grupo de recursos junto com o aplicativo de funções. Caso queira usar outra conta de armazenamento no aplicativo de funções, alterne para a guia Hospedagem para escolher uma conta.

  6. Clique em Examinar + Criar, depois em Criar.

Criar um projeto do Azure Functions localmente

Inicializar um aplicativo de funções

  1. Em uma linha de comando, crie uma pasta raiz para seu projeto e altere para a pasta.

  2. Execute o comando a seguir no terminal para criar um novo projeto do JavaScript Functions:

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

Por padrão, o projeto gerado inclui um arquivo host.json que contém os pacotes de extensão que incluem a extensão do SignalR. Para obter mais informações sobre pacotes de extensão, consulte Registrar as extensões de associação do Azure Functions.

Definir as configurações do aplicativo

Quando você executa e depura o runtime do Azure Functions localmente, o aplicativo de funções lê as configurações do aplicativo de local.settings.json. Atualize esse arquivo com a cadeias de conexão da instância do Serviço do Azure SignalR e a conta de armazenamento criada anteriormente.

Substitua o conteúdo do local.settings.json pelo código a seguir:

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

No código anterior:

  • Insira a cadeia de conexão de Serviço do Azure SignalR na configuração AzureSignalRConnectionString.

    Para obter a cadeia de caracteres, vá para a instância do Serviço do Azure SignalR no portal do Azure. Na seção Configurações, localize a configuração de Chaves. Selecione o botão Copiar à direita da cadeia de conexão para copiá-la para a área de transferência. Use a cadeia de conexão primária ou secundária.

  • Insira a cadeia de conexão da conta de armazenamento na configuração AzureWebJobsStorage.

    Para obter a cadeia de caracteres, acesse sua conta de armazenamento no portal do Azure. Na seção Segurança + rede, localize a configuração de chaves de acesso. Selecione o botão Copiar à direita da cadeia de conexão para copiá-la para a área de transferência. Use a cadeia de conexão primária ou secundária.

Está enfrentando problemas? Fale conosco.

Crie uma função para autenticar usuários no Serviço do Azure SignalR

Quando o aplicativo de chat é aberto pela primeira vez no navegador, ele exige credenciais de conexão válidas para se conectar ao Serviço Azure SignalR. Crie uma função de gatilho HTTP nomeada negotiate em seu aplicativo de funções para retornar essas informações de conexão.

Observação

Essa função deve ser nomeada negotiate porque o cliente SignalR requer um ponto de extremidade que termina em /negotiate.

  1. Na pasta raiz do projeto, crie a função negotiate a partir de um modelo interno usando o seguinte comando:

    func new --template "HTTP trigger" --name negotiate
    
  2. Abra src/functions/negotiate.js, atualize o conteúdo da seguinte maneira:

    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],
    });
    

    A função contém uma associação de gatilho HTTP para receber solicitações de clientes do SignalR. A função também contém uma associação de entrada do SignalR para gerar credenciais válidas para um cliente se conectar a um Hub de Serviço do Azure SignalR chamado default.

    Essa função usa as informações de conexão do SignalR da associação de entrada e a retorna para o cliente no corpo da resposta HTTP.

    Não há nenhuma propriedade userId na associação para desenvolvimento local signalRConnectionInfo. Você o adicionará posteriormente para definir o nome de usuário de uma conexão SignalR ao implantar o aplicativo de funções no Azure.

Está com problemas? Queremos saber.

Criar uma função para enviar mensagens de chat

O aplicativo Web também requer uma API HTTP para enviar mensagens de chat. Crie uma função de gatilho HTTP que envia mensagens para todos os clientes conectados que usam o Serviço do Azure SignalR:

  1. Na pasta raiz do projeto, crie uma função de gatilho HTTP nomeada sendMessage do modelo usando o seguinte comando:

    func new --name sendMessage --template "Http trigger"
    
  2. Abra o arquivo src/functions/sendMessage.js, atualize o conteúdo da seguinte maneira:

    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]
                });
        }
    });
    

    A função contém um gatilho HTTP e uma associação de saída do SignalR. Ela usa o corpo da solicitação HTTP e o envia para clientes conectados ao Serviço do Azure SignalR. Ele invoca uma função nomeada newMessage em cada cliente.

    A função pode ler a identidade do remetente e pode aceitar um valor de recipient no corpo da mensagem para permitir enviar uma mensagem privada para um único usuário. Você usará essas funcionalidades mais tarde no tutorial.

  3. Salve o arquivo.

Está enfrentando problemas? Fale conosco.

Hospedar a interface do usuário da Web do cliente de chat

A interface do usuário do aplicativo de chat é um SPA (aplicativo de página única) simples criado com a estrutura JavaScript Vue usando o Cliente JavaScript ASP.NET Core SignalR. Para simplificar, o aplicativo de funções hospeda a página da Web. Em um ambiente de produção, use Aplicativos Web Estáticos para hospedar a página da Web.

  1. Crie um arquivo chamado index.html no diretório raiz do projeto de função.

  2. Copie e cole o conteúdo de index.html em seu arquivo. Salve o arquivo.

  3. Na pasta raiz do projeto, crie uma função de gatilho HTTP nomeada index do modelo com o comando:

    func new --name index --template "Http trigger"
    
  4. Modifique o conteúdo de src/functions/index.js para o seguinte código:

    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,
            };
        }
    });
    

    A função lê a página da Web estática e a retorna ao usuário.

  5. Teste o aplicativo no local. Inicie o aplicativo de funções usando este comando:

    func start
    
  6. Abra http://localhost:7071/api/index no navegador da Web. Uma página da Web de chat deve aparecer.

    Captura de tela da interface do usuário da Web de um cliente de chat local.

  7. Insira uma mensagem na caixa de chat.

    Depois de selecionar a tecla Enter, a mensagem será exibida na página da Web. Como o nome de usuário do cliente SignalR não está definido, você está enviando todas as mensagens anonimamente.

Está com problemas? Queremos saber.

Implantar no Azure e habilitar autenticação

Você está executando o aplicativo de funções e o aplicativo de chat localmente. Agora, implante-os no Azure e habilite a autenticação e o sistema de mensagens privadas.

Configurar o aplicativo de funções para autenticação

Até agora, o aplicativo de chat funciona anonimamente. No Azure, será usada a Autenticação do Serviço de Aplicativo para autenticar o usuário. A ID ou o nome do usuário autenticado é passado para a associação SignalRConnectionInfo para gerar informações de conexão autenticadas como o usuário.

  1. Abra o arquivo src/functions/negotiate.js.

  2. Insira uma propriedade userId na associação inputSignalR com o valor {headers.x-ms-client-principal-name}. Esse valor é uma expressão de associação que define o nome de usuário do cliente do SignalR como o nome do usuário autenticado. A associação agora deve parecer assim:

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

Implantar o aplicativo de funções no Azure

Implante o aplicativo de funções no Azure usando o seguinte comando:

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

A opção --publish-local-settings publica suas configurações locais do arquivo local.settings.json no Azure, para que não seja necessário configurá-las novamente no Azure.

Habilitar autenticação do Serviço de Aplicativo

O Azure Functions dá suporte à autenticação com Microsoft Entra ID, Facebook, Twitter, conta Microsoft e Google. A Microsoft será usada como provedor de identidade para este tutorial.

  1. No portal do Azure, acesse a página de recursos do aplicativo de funções.

  2. Selecione Configurações>Autenticação.

  3. Selecione Adicionar provedor de identidade.

    Captura de tela da página Autenticação do aplicativo de funções e o botão para adicionar um provedor de identidade.

  4. Na lista do provedor de identidade, selecione Microsoft. Depois, selecione Adicionar.

    Captura de tela da página para adicionar um provedor de identidade.

As configurações concluídas criam um registro de aplicativo que associa seu provedor de identidade ao seu aplicativo de funções.

Para obter mais informações sobre os provedores de identidade com suporte, consulte os seguintes artigos:

Experimentar o aplicativo

  1. Abra https://<YOUR-FUNCTION-APP-NAME>.azurewebsites.net/api/index.
  2. Selecione Login para autenticar com o provedor de autenticação escolhido.
  3. Envie mensagens públicas inserindo-as na caixa de chat principal.
  4. Envie mensagens privadas selecionando um nome de usuário no histórico de chat. Somente o destinatário selecionado recebe essas mensagens.

Captura de tela de um aplicativo de chat do cliente online autenticado.

Parabéns! Você implantou um aplicativo de chat sem servidor em tempo real.

Está com problemas? Queremos saber.

Limpar recursos

Para limpar os recursos que você criou neste tutorial, exclua o grupo de recursos usando o portal do Azure.

Cuidado

Excluir o grupo de recursos exclui todos os recursos que ele contém. Se o grupo de recursos contiver recursos fora do escopo deste tutorial, eles também serão excluídos.

Está com problemas? Fale conosco.

Próximas etapas

Neste tutorial, você aprendeu a usar o Azure Functions com o Serviço Azure SignalR. Leia mais sobre a criação de aplicativos sem servidor em tempo real com associações do Serviço do Azure SignalR para o Azure Functions:

Está enfrentando problemas? Queremos saber.