Azure SignalR Service authentication (Autenticação do Azure SignalR Service)

Este tutorial continua no aplicativo de sala de chat introduzido em Criar uma sala de chat com o Serviço SignalR. Conclua esse início rápido primeiro para configurar sua sala de chat.

Neste tutorial, saiba como criar e integrar seu método de autenticação usando o Serviço SignalR do Microsoft Azure.

A autenticação utilizada inicialmente na aplicação de sala de chat do início rápido é demasiado simples para cenários do mundo real. A aplicação permite que cada cliente afirme a sua identidade e o servidor aceita-a simplesmente. Essa abordagem é ineficaz no mundo real porque usuários mal-intencionados podem usar identidades falsas para acessar dados confidenciais.

O GitHub disponibiliza APIs de autenticação baseadas num popular protocolo padrão da indústria, chamado OAuth. Essas APIs permitem que aplicações de terceiros autentiquem contas do GitHub. Neste tutorial, você pode usar essas APIs para implementar a autenticação por meio de uma conta do GitHub antes de permitir logins de cliente no aplicativo da sala de chat. Após a autenticação da conta do GitHub, as informações da conta serão adicionadas como um cookie a ser usado pelo cliente da Web para autenticação.

Para obter mais informações sobre as APIs de autenticação OAuth disponibilizadas através do GitHub, veja Basics of Authentication (Noções Básicas da Autenticação).

Pode utilizar qualquer editor de código para concluir os passos deste início rápido. No entanto, o Visual Studio Code é uma excelente opção, disponível nas plataformas Windows, macOS e Linux.

O código deste tutorial está disponível para transferência no repositório do GitHub AzureSignalR-samples.

OAuth Complete hosted in Azure

Neste tutorial, irá aprender a:

  • Registar uma aplicação de OAuth nova na sua conta do GitHub
  • Adicionar um controlador de autenticação para suportar a autenticação do GitHub
  • Implementar a aplicação Web ASP.NET Core no Azure

Se não tiver uma subscrição do Azure, crie uma conta gratuita do Azure antes de começar.

Pré-requisitos

Para concluir este tutorial, deve ter os seguintes pré-requisitos:

Criar uma aplicação de OAuth

  1. Abra um browser, navegue para https://github.com e inicie sessão na sua conta.

  2. Para sua conta, navegue até Configurações>Configurações Configurações do>desenvolvedor Aplicativos OAuth e selecione Novo Aplicativo OAuth em Aplicativos OAuth.

  3. Use as seguintes configurações para o novo aplicativo OAuth e selecione Registrar aplicativo:

    Nome da Definição Valor sugerido Description
    Nome da aplicação Chat to Azure SignalR O usuário do GitHub deve ser capaz de reconhecer e confiar no aplicativo com o qual está se autenticando.
    URL da home page https://localhost:5001
    Descrição da aplicação Um exemplo de sala de chat usando o Serviço Azure SignalR com autenticação GitHub Uma descrição útil do aplicativo que ajuda os usuários do aplicativo a entender o contexto da autenticação que está sendo usada.
    URL da chamada de retorno da autorização https://localhost:5001/signin-github Esta é a definição mais importante para a sua aplicação de OAuth. É o URL de chamada de retorno que o GitHub devolve ao utilizador após a autenticação com êxito. Neste tutorial, tem de utilizar o URL de chamada de retorno predefinido para o pacote AspNet.Security.OAuth.GitHub, /signin-github.
  4. Assim que o registo da aplicação de OAuth nova estiver concluído, adicione o Client ID (ID de Cliente) e o Client Secret (Segredo de Cliente) ao Secret Manager com os seguintes comandos. Substitua Your_GitHub_Client_Id (Seu_Id_de_cliente_do_GitHub) Your_GitHub_Client_Secret (Seu_Segredo_de_cliente_do_GitHub) pelos valores da sua aplicação de OAuth.

    dotnet user-secrets set GitHubClientId Your_GitHub_Client_Id
    dotnet user-secrets set GitHubClientSecret Your_GitHub_Client_Secret
    

Implementar o fluxo de OAuth

Vamos reutilizar o aplicativo de bate-papo criado no tutorial Criar uma sala de chat com o Serviço SignalR.

Atualização Program.cs para suportar a autenticação do GitHub

  1. Adicione uma referência aos pacotes AspNet.Security.OAuth.GitHub mais recentes e restaure todos os pacotes.

    dotnet add package AspNet.Security.OAuth.GitHub
    
  2. Abra Program.cs e atualize o código para o seguinte trecho de código:

    using Microsoft.AspNetCore.Authentication.Cookies;
    using Microsoft.AspNetCore.Authentication.OAuth;
    
    using System.Net.Http.Headers;
    using System.Security.Claims;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services
        .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie()
        .AddGitHub(options =>
        {
            options.ClientId = builder.Configuration["GitHubClientId"] ?? "";
            options.ClientSecret = builder.Configuration["GitHubClientSecret"] ?? "";
            options.Scope.Add("user:email");
            options.Events = new OAuthEvents
            {
                OnCreatingTicket = GetUserCompanyInfoAsync
            };
        });
    
    builder.Services.AddControllers();
    builder.Services.AddSignalR().AddAzureSignalR();
    
    var app = builder.Build();
    
    app.UseHttpsRedirection();
    app.UseDefaultFiles();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapControllers();
    app.MapHub<ChatSampleHub>("/chat");
    
    app.Run();
    
    static async Task GetUserCompanyInfoAsync(OAuthCreatingTicketContext context)
    {
        var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
    
        var response = await context.Backchannel.SendAsync(request,
            HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
        var user = await response.Content.ReadFromJsonAsync<GitHubUser>();
        if (user?.company != null)
        {
            context.Principal?.AddIdentity(new ClaimsIdentity(new[]
            {
                new Claim("Company", user.company)
            }));
        }
    }
    
    class GitHubUser
    {
        public string? company { get; set; }
    }
    

    Dentro do código, e são usados para adicionar suporte à autenticação com o aplicativo GitHub OAuth, AddAuthentication e o método auxiliar é um código de exemplo mostrando como carregar as informações da empresa do GitHub OAuth e UseAuthenticationGetUserCompanyInfoAsync salvar na identidade do usuário. Você também pode notar que é usado desde o GitHub OAuth definir secure cookie que só passa para o UseHttpsRedirection() esquema segurohttps. Também não se esqueça de atualizar o local Properties/lauchSettings.json para adicionar o ponto de extremidade https:

    {
      "profiles": {
        "GitHubChat" : {
          "commandName": "Project",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          },
          "applicationUrl": "http://0.0.0.0:5000/;https://0.0.0.0:5001/;"
        }
      }
    }
    

Adicionar um controlador de autenticação

Nesta seção, você implementa uma Login API que autentica clientes usando o aplicativo GitHub OAuth. Uma vez autenticada, a API adiciona um cookie à resposta do cliente da Web antes de redirecioná-lo de volta para o aplicativo de bate-papo. Esse cookie é então utilizado para identificar o cliente.

  1. Adicione um novo arquivo de código do controlador ao diretório GitHubChat\Controllers . Dê o nome AuthController.cs ao ficheiro.

  2. Adicione o seguinte código ao controlador de autenticação. Certifique-se de atualizar o namespace, se o diretório do projeto não for o GitHubChat:

    using AspNet.Security.OAuth.GitHub;
    
    using Microsoft.AspNetCore.Authentication;
    using Microsoft.AspNetCore.Mvc;
    
    namespace GitHubChat.Controllers
    {
        [Route("/")]
        public class AuthController : Controller
        {
            [HttpGet("login")]
            public IActionResult Login()
            {
                if (User.Identity == null || !User.Identity.IsAuthenticated)
                {
                    return Challenge(GitHubAuthenticationDefaults.AuthenticationScheme);
                }
    
                HttpContext.Response.Cookies.Append("githubchat_username", User.Identity.Name ?? "");
                HttpContext.SignInAsync(User);
                return Redirect("/");
            }
        }
    }
    
  3. Guardar as suas alterações.

Atualizar a classe Hub

Por padrão, o cliente Web se conecta ao Serviço SignalR usando um token de acesso gerado pelo SDK do Azure SignalR automaticamente.

Nesta seção, você integra o fluxo de trabalho de autenticação real adicionando o atributo à classe de hub e atualiza os métodos de hub para ler o Authorize nome de usuário da declaração do usuário autenticado.

  1. Abra Hub\ChatSampleHub.cs e atualize o código para o trecho de código abaixo. O código adiciona o Authorize atributo à ChatSampleHub classe e usa a identidade autenticada do usuário nos métodos de hub. Além disso, o OnConnectedAsync método é adicionado, que registra uma mensagem do sistema na sala de chat cada vez que um novo cliente se conecta.

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.SignalR;
    
    [Authorize]
    public class ChatSampleHub : Hub
    {
        public override Task OnConnectedAsync()
        {
            return Clients.All.SendAsync("broadcastMessage", "_SYSTEM_", $"{Context.User?.Identity?.Name} JOINED");
        }
    
        // Uncomment this line to only allow user in Microsoft to send message
        //[Authorize(Policy = "Microsoft_Only")]
        public Task BroadcastMessage(string message)
        {
            return Clients.All.SendAsync("broadcastMessage", Context.User?.Identity?.Name, message);
        }
    
        public Task Echo(string message)
        {
            var echoMessage = $"{message} (echo from server)";
            return Clients.Client(Context.ConnectionId).SendAsync("echo", Context.User?.Identity?.Name, echoMessage);
        }
    }
    
  2. Guardar as suas alterações.

Atualizar o código do cliente Web

  1. Abra wwwroot\index.html e substitua o código que pede o nome de utilizador pelo código para utilizar o cookie que o controlador de autenticação devolve.

    Atualize o código dentro da função getUserName index.htmlpara o seguinte para usar cookies:

    function getUserName() {
      // Get the user name cookie.
      function getCookie(key) {
        var cookies = document.cookie.split(";").map((c) => c.trim());
        for (var i = 0; i < cookies.length; i++) {
          if (cookies[i].startsWith(key + "="))
            return unescape(cookies[i].slice(key.length + 1));
        }
        return "";
      }
      return getCookie("githubchat_username");
    }
    
  2. Função de atualização onConnected para remover o parâmetro ao invocar o username método broadcastMessage hub e echo:

    function onConnected(connection) {
      console.log("connection started");
      connection.send("broadcastMessage", "_SYSTEM_", username + " JOINED");
      document.getElementById("sendmessage").addEventListener("click", function (event) {
        // Call the broadcastMessage method on the hub.
        if (messageInput.value) {
          connection.invoke("broadcastMessage", messageInput.value)
            .catch((e) => appendMessage("_BROADCAST_", e.message));
        }
    
        // Clear text box and reset focus for next comment.
        messageInput.value = "";
        messageInput.focus();
        event.preventDefault();
      });
      document.getElementById("message").addEventListener("keypress", function (event) {
        if (event.keyCode === 13) {
          event.preventDefault();
          document.getElementById("sendmessage").click();
          return false;
        }
      });
      document.getElementById("echo").addEventListener("click", function (event) {
        // Call the echo method on the hub.
        connection.send("echo", messageInput.value);
    
        // Clear text box and reset focus for next comment.
        messageInput.value = "";
        messageInput.focus();
        event.preventDefault();
      });
    }
    
  3. Na parte inferior do index.html, atualize o manipulador de erros conforme connection.start() mostrado abaixo para solicitar que o usuário entre.

    connection.start()
      .then(function () {
        onConnected(connection);
      })
      .catch(function (error) {
        console.error(error.message);
        if (error.statusCode && error.statusCode === 401) {
          appendMessage(
            "_BROADCAST_",
            "You\"re not logged in. Click <a href="/login">here</a> to login with GitHub."
          );
        }
      });
    
  4. Guardar as suas alterações.

Compilar e executar a aplicação localmente

  1. Guarde as alterações a todos os ficheiros.

  2. Execute o seguinte comando para executar o aplicativo Web localmente:

    dotnet run
    

    O aplicativo é hospedado localmente na porta 5000 por padrão:

    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://0.0.0.0:5000
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: https://0.0.0.0:5001
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Development
    
  3. Inicie uma janela do browser e navegue para https://localhost:5001. Selecione o link aqui na parte superior para entrar com o GitHub.

    OAuth Complete hosted in Azure

    Você será solicitado a autorizar o acesso do aplicativo de bate-papo à sua conta do GitHub. Selecione o botão Autorizar .

    Authorize OAuth App

    Você é redirecionado de volta para o aplicativo de bate-papo e faz login com o nome da sua conta no GitHub. O aplicativo Web determinou o nome da sua conta autenticando-o usando a nova autenticação adicionada.

    Account identified

    Com o aplicativo de bate-papo agora executa a autenticação com o GitHub e armazena as informações de autenticação como cookies, a próxima etapa envolve implantá-lo no Azure. Essa abordagem permite que outros usuários se autentiquem usando suas respetivas contas e se comuniquem a partir de várias estações de trabalho.

Implementar a aplicação no Azure

Prepare seu ambiente para a CLI do Azure:

  • Use o ambiente Bash no Azure Cloud Shell. Para obter mais informações, consulte Guia de início rápido para Bash no Azure Cloud Shell.

  • Se preferir executar comandos de referência da CLI localmente, instale a CLI do Azure. Se estiver a utilizar o Windows ou macOS, considere executar a CLI do Azure num contentor Docker. Para obter mais informações, consulte Como executar a CLI do Azure em um contêiner do Docker.

    • Se estiver a utilizar uma instalação local, inicie sessão no CLI do Azure ao utilizar o comando az login. Para concluir o processo de autenticação, siga os passos apresentados no seu terminal. Para outras opções de entrada, consulte Entrar com a CLI do Azure.

    • Quando solicitado, instale a extensão da CLI do Azure na primeira utilização. Para obter mais informações sobre as extensões, veja Utilizar extensões com o CLI do Azure.

    • Execute o comando az version para localizar a versão e as bibliotecas dependentes instaladas. Para atualizar para a versão mais recente, execute o comando az upgrade.

Nesta seção, você usa a CLI do Azure para criar um novo aplicativo Web no Serviço de Aplicativo do Azure para hospedar seu aplicativo ASP.NET no Azure. O aplicativo Web está configurado para usar a implantação local do Git. O aplicativo Web também é configurado com sua cadeia de conexão SignalR, segredos do aplicativo GitHub OAuth e um usuário de implantação.

Quando criar os seguintes recursos, confirme que utiliza o mesmo grupo de recursos no qual o recurso do SignalR Service reside. Essa abordagem torna a limpeza muito mais fácil mais tarde quando você deseja remover todos os recursos. Os exemplos mostrados partem do princípio de que utilizou o nome do grupo recomendado nos tutoriais anteriores, SignalRTestResources.

Criar a aplicação Web e o plano

Copie o texto dos comandos abaixo e atualize os parâmetros. Cole o script atualizado no Azure Cloud Shell e prima Enter para criar um plano do Serviço de Aplicações novo e uma aplicação Web nova.

#========================================================================
#=== Update these variable for your resource group name.              ===
#========================================================================
ResourceGroupName=SignalRTestResources

#========================================================================
#=== Update these variable for your web app.                          ===
#========================================================================
WebAppName=myWebAppName
WebAppPlan=myAppServicePlanName

# Create an App Service plan.
az appservice plan create --name $WebAppPlan --resource-group $ResourceGroupName \
    --sku FREE

# Create the new Web App
az webapp create --name $WebAppName --resource-group $ResourceGroupName \
    --plan $WebAppPlan
Parâmetro Description
ResourceGroupName Este nome de grupo de recursos foi sugerido nos tutoriais anteriores. É uma boa ideia manter todos os recursos do tutorial agrupados. Utilize o mesmo grupo de recursos que utilizou nos tutoriais anteriores.
WebAppPlan Introduza um nome exclusivo novo para o Plano do Serviço de Aplicações.
WebAppName Este parâmetro é o nome do novo aplicativo Web e parte da URL. Torne-o único. Por exemplo, signalrtestwebapp22665120.

Adicionar as definições da aplicação à aplicação Web

Nesta seção, você adiciona configurações de aplicativo para os seguintes componentes:

  • Cadeia de ligação do recurso do SignalR Service
  • ID do cliente da aplicação de OAuth do GitHub
  • Segredo do cliente da aplicação de OAuth do GitHub

Copie o texto dos comandos abaixo e atualize os parâmetros. Cole o script atualizado no Azure Cloud Shell e prima Enter para adicionar as definições da aplicação:

#========================================================================
#=== Update these variables for your GitHub OAuth App.                ===
#========================================================================
GitHubClientId=1234567890
GitHubClientSecret=1234567890

#========================================================================
#=== Update these variables for your resources.                       ===
#========================================================================
ResourceGroupName=SignalRTestResources
SignalRServiceResource=mySignalRresourcename
WebAppName=myWebAppName

# Get the SignalR primary connection string
primaryConnectionString=$(az signalr key list --name $SignalRServiceResource \
  --resource-group $ResourceGroupName --query primaryConnectionString -o tsv)

#Add an app setting to the web app for the SignalR connection
az webapp config appsettings set --name $WebAppName \
    --resource-group $ResourceGroupName \
    --settings "Azure__SignalR__ConnectionString=$primaryConnectionString"

#Add the app settings to use with GitHub authentication
az webapp config appsettings set --name $WebAppName \
    --resource-group $ResourceGroupName \
    --settings "GitHubClientId=$GitHubClientId"
az webapp config appsettings set --name $WebAppName \
    --resource-group $ResourceGroupName \
    --settings "GitHubClientSecret=$GitHubClientSecret"
Parâmetro Description
GitHubClientId Atribua a essa variável a ID do cliente secreta para seu aplicativo OAuth do GitHub.
GitHubClientSecret Atribua a esta variável a palavra-passe secreta da aplicação de OAuth do GitHub.
ResourceGroupName Atualize esta variável para ser o mesmo nome de grupo de recursos que utilizou na secção anterior.
SignalRServiceResource Atualize esta variável com o nome do recurso do SignalR Service que criou no início rápido. Por exemplo, signalrtestsvc48778624.
WebAppName Atualize esta variável com o nome da nova aplicação Web que criou na secção anterior.

Configurar a aplicação Web para implementação no Git local

No Azure Cloud Shell, cole o seguinte script. Esse script cria um novo nome de usuário e senha de implantação que você usa ao implantar seu código no aplicativo Web com o Git. O script também configura a aplicação Web para implementação com um repositório de Git local e devolve o URL de implementação do Git.

#========================================================================
#=== Update these variables for your resources.                       ===
#========================================================================
ResourceGroupName=SignalRTestResources
WebAppName=myWebAppName

#========================================================================
#=== Update these variables for your deployment user.                 ===
#========================================================================
DeploymentUserName=myUserName
DeploymentUserPassword=myPassword

# Add the desired deployment user name and password
az webapp deployment user set --user-name $DeploymentUserName \
    --password $DeploymentUserPassword

# Configure Git deployment and note the deployment URL in the output
az webapp deployment source config-local-git --name $WebAppName \
    --resource-group $ResourceGroupName \
    --query [url] -o tsv
Parâmetro Description
DeploymentUserName Escolha um nome de utilizador de implementação novo.
DeploymentUserPassword Escolha uma palavra-passe para o utilizador de implementação novo.
ResourceGroupName Utilize o mesmo nome do grupo de recursos que utilizou na secção anterior.
WebAppName Este parâmetro é o nome do novo aplicativo Web criado anteriormente.

Anote o URL de implementação do Git que este comando devolve. Utilize este URL mais tarde.

Implementar o código na aplicação Web do Azure

Para implementar o código, execute os seguintes comandos numa shell do Git.

  1. Navegue para a raiz do diretório do projeto. Se não tiver o projeto inicializado com um repositório do Git, execute os seguintes comandos:

    git init
    
  2. Adicione um remoto para o URL de implementação do Git que apontou anteriormente:

    git remote add Azure <your git deployment url>
    
  3. Coloque todos os ficheiros no repositório inicializado e adicione uma consolidação.

    git add -A
    git commit -m "init commit"
    
  4. Implemente o código na aplicação Web no Azure.

    git push Azure main
    

    Você será solicitado a autenticar para implantar o código no Azure. Introduza o nome de utilizador e a palavra-passe do utilizador de implementação que criou acima.

Atualizar a aplicação de OAuth do GitHub

A última coisa que tem de fazer é atualizar o URL da home page e o URL da chamada de retorno da autorização da aplicação de OAuth do GitHub para apontar para a nova aplicação alojada.

  1. Abra https://github.com num browser e navegue para Settings (Definições) >Developer settings (Definições do programador) >Oauth Apps (Aplicações de OAuth), na sua conta.

  2. Selecione no seu aplicativo de autenticação e atualize o URL da página inicial e o URL de retorno de chamada de autorização, conforme mostrado abaixo:

    Definição Exemplo
    URL da home page https://signalrtestwebapp22665120.azurewebsites.net
    URL da chamada de retorno da autorização https://signalrtestwebapp22665120.azurewebsites.net/signin-github
  3. Navegue para o URL da aplicação Web e teste a aplicação.

    OAuth Complete hosted in Azure

Clean up resources (Limpar recursos)

Se você continuar para o próximo tutorial, você pode manter os recursos criados neste início rápido e reutilizá-los com o próximo tutorial.

Caso contrário, se tiver terminado o aplicativo de exemplo de início rápido, você poderá excluir os recursos do Azure criados neste início rápido para evitar cobranças.

Importante

A eliminação de um grupo de recursos é irreversível e o grupo de recursos e todos os recursos contidos no mesmo serão permanentemente eliminados. Confirme que não elimina acidentalmente o grupo de recursos ou recursos errados. Se tiver criado os recursos para alojar este exemplo num grupo de recursos existente que contém os recursos que pretende manter, poderá eliminar cada recurso individualmente nos respetivos painéis em vez de eliminar o grupo de recursos.

Inicie sessão no Portal do Azure e selecione Grupos de recursos.

Na caixa de texto Filtrar por nome..., escreva o nome do grupo de recursos. As instruções neste artigo utilizaram um grupo de recursos denominado SignalRTestResources. No seu grupo de recursos na lista de resultados, clique em ... e em Eliminar grupo de recursos.

Delete

É-lhe pedido que confirme a eliminação do grupo de recursos. Digite o nome do grupo de recursos a ser confirmado e selecione Excluir.

Após alguns instantes, o grupo de recursos e todos os recursos contidos no mesmo são eliminados.

Próximos passos

Neste tutorial, adicionou a autenticação com OAuth para proporcionar uma melhor abordagem à autenticação com o Azure SignalR Service. Para saber mais sobre como utilizar o Azure SignalR Service, avance para os exemplos da CLI do Azure para SignalR Service.