Partilhar via


Proteja um aplicativo ASP.NET Core Blazor WebAssembly hospedado com o Microsoft Entra ID

Important

O modelo de projeto Hosted Blazor WebAssembly foi removido da estrutura com o lançamento do .NET 8 (novembro de 2023). As orientações neste artigo só são suportadas para o .NET 7 ou anterior. Os aplicativos de Blazor WebAssembly hospedados que são atualizados a cada versão continuam a receber suporte ao produto. Como alternativa, refatore a aplicação numa aplicação Blazor WebAssembly independente ou numa Blazor Web App.

Este artigo explica como criar um Blazor WebAssembly de solução de hospedado que usa do Microsoft Entra ID (ME-ID) para autenticação. Este artigo concentra-se numa única aplicação de inquilino com um único registo de aplicação Azure de inquilino.

Este artigo não abrange um registro de ME-ID multilocatário. Para obter mais informações, consulte Tornando seu aplicativo multilocatário.

Este artigo se concentra no uso de um locatário do Microsoft Entra, conforme descrito em Guia de início rápido: configurar um locatário. Se a aplicação estiver registada num inquilino Azure Active Directory B2C, tal como descrito em Tutorial: Criar um inquilino do Azure Active Directory B2C, mas seguir as orientações neste artigo, o URI da ID da Aplicação é gerido de forma diferente pelo ME-ID. Para obter mais informações, consulte a seção 'Uso de um locatário do Azure Active Directory B2C' deste artigo.

Para obter cobertura adicional de cenários de segurança depois de ler este artigo, consulte ASP.NET Core Blazor WebAssembly cenários de segurança adicionais.

Walkthrough

As subseções do passo a passo explicam como:

  • Criar um locatário no Azure
  • Registrar um aplicativo de API de servidor no Azure
  • Registrar um aplicativo cliente no Azure
  • Criar a aplicação Blazor
  • Modificar a configuração do Serverappsettings.json
  • Modificar o esquema de escopo de token de acesso padrão
  • Executar o aplicativo

Criar um locatário no Azure

Siga as orientações em Guia de início rápido: configurar o inquilino para criar um inquilino no ME-ID.

Registrar um aplicativo de API de servidor no Azure

Registre um aplicativo ME-ID para o aplicativo de API do Server:

  1. Navegue até Microsoft Entra ID no portal do Azure. Selecione Aplicativos>Registros de aplicativos na barra lateral. Selecione o botão Novo de registo.
  2. Forneça um nome para a aplicação (por exemplo, ME-IDBlazor Server).
  3. Escolha um dos tipos de conta suportados . Você pode selecionar Contas neste diretório organizacional somente (locatário único) para essa experiência.
  4. A aplicação de API do Server não requer um URI de redirecionamento nesta situação, portanto, deixe a lista suspensa Selecionar uma plataforma sem seleção e não insira um URI de redirecionamento.
  5. Este artigo pressupõe que o aplicativo esteja registrado em um locatário Microsoft Entra. Se a aplicação estiver registada num locatário Azure Active Directory B2C, a caixa de seleção Permissões>Conceder consentimento de administrador para permissões openid e offline_access estará presente e selecionada. Desmarque a caixa de seleção para desativar a configuração. Ao utilizar um locatário do Directório Ativo do Azure, a caixa de seleção não está presente.
  6. Selecione Register.

Registe as seguintes informações:

  • Aplicativo de API do Server ID do aplicativo (cliente) (por exemplo, 00001111-aaaa-2222-bbbb-3333cccc4444)
  • ID do diretório (inquilino) (por exemplo, aaaabbbb-0000-cccc-1111-dddd2222eeee)
  • ME-ID Domínio Principal/Editor/Locatário (por exemplo, contoso.onmicrosoft.com): o domínio está disponível como domínio do Editor na folha de Identidade Visual do portal do Azure para a aplicação registrada.

Em permissões de API, remova a permissão Microsoft Graph>User.Read, pois o aplicativo de API do servidor não requer acesso adicional à API para apenas fazer login de utilizadores e chamar endpoints da API do servidor.

Em Expor uma API:

  1. Confirme ou adicione o de URI da ID do aplicativo no formato api://{SERVER API APP CLIENT ID}.
  2. Selecione Adicionar um escopo.
  3. Selecione Salvar e continue.
  4. Forneça um nome de escopo (por exemplo, API.Access).
  5. Forneça um nome de exibição para o consentimento do administrador (por exemplo, Access API).
  6. Forneça uma descrição do consentimento do administrador (por exemplo, Allows the app to access server app API endpoints.).
  7. Confirme que o Estado está definido como Ativado.
  8. Selecione Adicionar escopo.

Registe as seguintes informações:

  • GUID URI ID da aplicação (por exemplo, registro 00001111-aaaa-2222-bbbb-3333cccc4444 do URI do ID da aplicação de api://00001111-aaaa-2222-bbbb-3333cccc4444)
  • Nome do escopo (por exemplo, API.Access)

Important

Se um valor personalizado for usado para o URI da ID do aplicativo, as alterações de configuração serão necessárias para os aplicativos Server e Client depois que os aplicativos forem criados a partir do modelo de projeto Blazor WebAssembly. Para obter mais informações, consulte a seção Uso de um URI de ID de aplicação personalizado.

Registrar um aplicativo cliente no Azure

Registe uma aplicação ME-ID para a aplicação Cliente :

  1. Navegue até Microsoft Entra ID no portal do Azure. Selecione registos de aplicações na barra lateral. Selecione o botão Novo de registo.
  2. Forneça um Nome para a aplicação (por exemplo, Cliente ME-IDBlazor).
  3. Escolha um dos tipos de conta suportados . Você pode selecionar Contas neste diretório organizacional somente (locatário único) para essa experiência.
  4. Defina a lista suspensa URI de Redirecionamento como Aplicativo de Página Única (SPA) e forneça o seguinte URI de redirecionamento: https://localhost/authentication/login-callback. Se você souber o URI de redirecionamento de produção para o host padrão do Azure (por exemplo, azurewebsites.net) ou o host de domínio personalizado (por exemplo, contoso.com), também poderá adicionar o URI de redirecionamento de produção ao mesmo tempo em que fornece o URI de redirecionamento de localhost. Certifique-se de incluir o número da porta para portas que não sejam:443 em quaisquer URIs de redirecionamento de produção que adicionar.
  5. Este artigo pressupõe que o aplicativo esteja registrado em um locatário Microsoft Entra. Se a aplicação estiver registada num locatário Azure Active Directory B2C, a caixa de seleção Permissões>Conceder consentimento de administrador para permissões openid e offline_access estará presente e selecionada. Desmarque a caixa de seleção para desativar a configuração. Ao utilizar um locatário do Directório Ativo do Azure, a caixa de seleção não está presente.
  6. Selecione Register.

Note

Não é obrigatório fornecer o número da porta para um URI de redirecionamento de localhost ME-ID. Para obter mais informações, consulte Restrições e limitações de URI de redirecionamento (URL de resposta): exceções Localhost (documentação do Entra).

Registe o ID da aplicação Client (cliente) (por exemplo, 11112222-bbbb-3333-cccc-4444dddd5555).

Em configurações de Autenticação>Plataforma>Aplicativo de página única:

  1. Confirme se o URI de redirecionamento do https://localhost/authentication/login-callback está presente.
  2. Na seção de concessão implícita , verifique se as caixas de seleção para tokens de acesso e tokens de ID não estão marcadas. A concessão implícita não é recomendada para aplicativos Blazor que usam o MSAL v2.0 ou posterior. Para obter mais informações, consulte Secure ASP.NET Core Blazor WebAssembly.
  3. Os padrões restantes para o aplicativo são aceitáveis para esta experiência.
  4. Selecione o botão Salvar se tiver feito alterações.

Em as permissões da API:

  1. Confirme se o aplicativo tem permissão >do Microsoft Graph User.Read.
  2. Selecione Adicionar uma permissão seguida por As Minhas APIs.
  3. Selecione a aplicação Server API na coluna Nome (por exemplo, Blazor Server ME-ID). Você deve ser proprietário do registro do aplicativo (e do registro do aplicativo de API, se for um aplicativo separado) para ver a API na área Minhas APIs do portal do Azure. Para obter mais informações, consulte Atribuir proprietário do aplicativo (documentação do Microsoft Entra).
  4. Abra a lista de API .
  5. Habilite o acesso à API (por exemplo, API.Access).
  6. Selecione Adicionar permissões.
  7. Selecione o botão Conceder consentimento de administrador para {TENANT NAME}. Selecione Sim para confirmar.

Important

Se você não tiver autoridade para conceder consentimento de administrador ao locatário na última etapa de configuração de permissões de API porque o consentimento para usar o aplicativo é delegado aos usuários, deverá executar as seguintes etapas adicionais:

  • O aplicativo deve usar um domínio de editor confiável.
  • Na configuração do aplicativo Server no portal do Azure, selecione a opção Expor uma API . Em Aplicativos cliente autorizados, selecione o botão para Adicionar um aplicativo cliente. Adicione o ID de Aplicação (cliente) da aplicação Client (por exemplo, 11112222-bbbb-3333-cccc-4444dddd5555).

Criar a aplicação Blazor

Numa pasta vazia, substitua os marcadores de posição no comando a seguir pelas informações registadas anteriormente e execute o comando num shell de comandos:

dotnet new blazorwasm -au SingleOrg --api-client-id "{SERVER API APP CLIENT ID}" --app-id-uri "{SERVER API APP ID URI GUID}" --client-id "{CLIENT APP CLIENT ID}" --default-scope "{DEFAULT SCOPE}" --domain "{TENANT DOMAIN}" -ho -o {PROJECT NAME} --tenant-id "{TENANT ID}"

Warning

Evite usar traços (-) no nome do aplicativo {PROJECT NAME} que interrompam a formação do identificador do aplicativo OIDC. A lógica no modelo de projeto Blazor WebAssembly usa o nome do projeto para um identificador de aplicativo OIDC na configuração da solução. Pascal case (BlazorSample) ou underscores (Blazor_Sample) são alternativas aceitáveis. Para mais informações, consulte Traços no nome de um projeto hospedado Blazor WebAssembly quebram a segurança OIDC (dotnet/aspnetcore #35337).

Placeholder Nome do portal do Azure Example
{PROJECT NAME} BlazorSample
{CLIENT APP CLIENT ID} ID do aplicativo (cliente) para o aplicativo Client 11112222-bbbb-3333-cccc-4444dddd5555
{DEFAULT SCOPE} Nome do escopo API.Access
{SERVER API APP CLIENT ID} ID da aplicação (cliente) para a aplicação API do Servidor 00001111-aaaa-2222-bbbb-3333cccc4444
{SERVER API APP ID URI GUID} ID do aplicativo URI GUID 00001111-aaaa-2222-bbbb-3333cccc4444 (GUID APENAS, corresponde ao {SERVER API APP CLIENT ID})
{TENANT DOMAIN} Domínio principal/editor/locatário contoso.onmicrosoft.com
{TENANT ID} ID do diretório (inquilino) aaaabbbb-0000-cccc-1111-dddd2222eeee

O local de saída especificado com a opção -o|--output cria uma pasta de projeto se ela não existir e se torna parte do nome do projeto. Evite usar traços (-) no nome do aplicativo que interrompam a formação do identificador do aplicativo OIDC (consulte o AVISO anterior).

Important

Se um valor personalizado for usado para o URI da ID do aplicativo, as alterações de configuração serão necessárias para os aplicativos Server e Client depois que os aplicativos forem criados a partir do modelo de projeto Blazor WebAssembly. Para obter mais informações, consulte a seção Uso de um URI de ID de aplicação personalizado.

Executar o aplicativo

Execute o aplicativo a partir do projeto Server. Ao usar o Visual Studio, pode:

  • Selecione a seta para baixo junto ao botão Executar. Abra Configurar Projetos de Inicialização na lista suspensa. Selecione a opção de projeto de inicialização único . Confirme ou altere o projeto de inicialização para o projeto Server.

  • Confirme se o projeto Server está realçado no Gerenciador de Soluções antes de iniciar o aplicativo com qualquer uma das seguintes abordagens:

    • Selecione o botão Executar.
    • Use Depurar>Iniciar a Depuração no menu.
    • Pressione F5.
  • Em um shell de comando, navegue até a pasta de projeto Server da solução. Execute o comando dotnet watch (ou dotnet run).

Configurar User.Identity.Name

As orientações nesta seção abrangem o preenchimento opcional de User.Identity.Name com o valor da declaração de name.

A API do aplicativo Server preenche User.Identity.Name com o valor do tipo de declaração http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name (por exemplo, bbbb0000-cccc-1111-dddd-2222eeee3333@contoso.onmicrosoft.com).

Para configurar a aplicação para receber o valor do tipo de pedido name:

Partes da solução

Esta seção descreve as partes de uma solução geradas a partir do modelo de projeto Blazor WebAssembly e descreve como os projetos Client e Server da solução são configurados para referência. Não há nenhuma orientação específica a ser seguida nesta seção para uma aplicação básica funcional se você criou a aplicação usando a orientação na seção Passo a Passo. As orientações nesta seção são úteis para atualizar um aplicativo para autenticar e autorizar usuários. No entanto, uma abordagem alternativa para atualizar uma aplicação é criar uma nova aplicação a partir das orientações na secção Passo a Passo e mover os componentes, classes e recursos da aplicação original para a nova.

appsettings.json configuração

Esta seção diz respeito ao aplicativo Server da solução.

O arquivo appsettings.json contém as opções para configurar o manipulador de portador JWT usado para validar tokens de acesso. Adicione a seguinte seção de configuração AzureAd:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "{TENANT DOMAIN}",
    "TenantId": "{TENANT ID}",
    "ClientId": "{SERVER API APP CLIENT ID}",
    "CallbackPath": "/signin-oidc",
    "Scopes": "{SCOPES}"
  }
}

Example:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "contoso.onmicrosoft.com",
    "TenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
    "ClientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
    "CallbackPath": "/signin-oidc",
    "Scopes": "API.Access"
  }
}

Important

Se o aplicativo Server estiver registrado para usar um URI de ID de Aplicativo personalizado em ME-ID (não no formato padrão api://{SERVER API APP CLIENT ID}), consulte a seção Uso de um URI de ID de Aplicativo personalizado. São necessárias alterações nas aplicações Server e Client.

Pacote de autenticação

Esta seção diz respeito ao aplicativo Server da solução.

O suporte para autenticar e autorizar chamadas para APIs Web ASP.NET Core com a plataforma de identidade da Microsoft é fornecido pelo pacote Microsoft.Identity.Web.

Note

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos na seção Instalar e gerenciar pacotes em Workflow de utilização de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

O aplicativo Server de uma solução de Blazor hospedada criada a partir do modelo Blazor WebAssembly inclui o pacote Microsoft.Identity.Web.UI. O pacote adiciona UI para autenticação de utilizadores em aplicações web e não é usado pelo framework Blazor. Se o aplicativo Server não for usado para autenticar usuários diretamente, é seguro remover a referência de pacote do arquivo de projeto do aplicativo Server.

Suporte ao serviço de autenticação

Esta seção diz respeito ao aplicativo Server da solução.

O método AddAuthentication configura serviços de autenticação dentro do aplicativo e configura o manipulador JWT Bearer como o método de autenticação padrão. O método AddMicrosoftIdentityWebApi configura serviços para proteger a API da Web com a plataforma de identidade Microsoft v2.0. Esse método espera uma seção AzureAd na configuração do aplicativo com as configurações necessárias para inicializar as opções de autenticação.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));

Note

Quando um único esquema de autenticação é registrado, o esquema de autenticação é usado automaticamente como o esquema padrão do aplicativo, e não é necessário declarar o esquema para AddAuthentication ou via AuthenticationOptions. Para obter mais informações, consulte Visão geral da autenticação do ASP.NET Core e o anúncio do ASP.NET Core (aspnet/Announcements #490).

UseAuthentication e UseAuthorization asseguram que:

  • O aplicativo tenta analisar e validar tokens em solicitações recebidas.
  • Qualquer solicitação que tente acessar um recurso protegido sem as credenciais adequadas falha.
app.UseAuthentication();
app.UseAuthorization();

WeatherForecast controlador

Esta seção diz respeito ao aplicativo Server da solução.

O controlador WeatherForecast (Controllers/WeatherForecastController.cs) expõe uma API protegida com o atributo [Authorize] aplicado ao controlador. É importante entender que:

  • O atributo [Authorize] neste controlador de API é a única coisa que protege essa API de acesso não autorizado.
  • O atributo [Authorize] usado no aplicativo Blazor WebAssembly serve apenas como uma dica para o aplicativo de que o usuário deve ser autorizado para que o aplicativo funcione corretamente.
[Authorize]
[ApiController]
[Route("[controller]")]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        ...
    }
}

wwwroot/appsettings.json configuração

Esta seção diz respeito ao aplicativo Client da solução.

A configuração é fornecida pelo arquivo wwwroot/appsettings.json:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/{TENANT ID}",
    "ClientId": "{CLIENT APP CLIENT ID}",
    "ValidateAuthority": true
  }
}

Example:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/e86c78e2-...-918e0565a45e",
    "ClientId": "11112222-bbbb-3333-cccc-4444dddd5555",
    "ValidateAuthority": true
  }
}

Pacote de autenticação

Esta seção diz respeito ao aplicativo Client da solução.

Quando um aplicativo é criado para usar Contas Corporativas ou Escolares (SingleOrg), o aplicativo recebe automaticamente uma referência de pacote para o Biblioteca de Autenticação da Microsoft (Microsoft.Authentication.WebAssembly.Msal). O pacote fornece um conjunto de primitivos que ajudam o aplicativo a autenticar usuários e obter tokens para chamar APIs protegidas.

Se adicionar autenticação a um aplicativo, adicione manualmente o pacote Microsoft.Authentication.WebAssembly.Msal ao aplicativo.

Note

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos na seção Instalar e gerenciar pacotes em Workflow de utilização de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

O pacote Microsoft.Authentication.WebAssembly.Msal adiciona transitivamente o pacote Microsoft.AspNetCore.Components.WebAssembly.Authentication ao aplicativo.

Suporte ao serviço de autenticação

Esta seção diz respeito ao aplicativo Client da solução.

É adicionado suporte para instâncias HttpClient que incluem tokens de acesso ao fazer solicitações para o aplicativo Server.

No ficheiro Program:

builder.Services.AddHttpClient("{PROJECT NAME}.ServerAPI", client => 
        client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient("{PROJECT NAME}.ServerAPI"));

O placeholder {PROJECT NAME} é o nome do projeto na criação da solução. Por exemplo, fornecer um nome de projeto como BlazorSample gera um HttpClient denominado BlazorSample.ServerAPI.

O suporte para autenticação de usuários é registrado no contêiner de serviço com o método de extensão AddMsalAuthentication fornecido pelo pacote Microsoft.Authentication.WebAssembly.Msal. Esse método configura os serviços necessários para que o aplicativo interaja com o Identity Provider (IP).

No ficheiro Program:

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});

O método AddMsalAuthentication aceita um callback para configurar os parâmetros necessários para autenticar uma app. Os valores necessários para configurar o aplicativo podem ser obtidos na configuração de ME-ID do Portal do Azure quando você registra o aplicativo.

Escopos de token de acesso

Esta seção diz respeito ao aplicativo Client da solução.

Os escopos de token de acesso padrão representam a lista de escopos de token de acesso que são:

  • Incluído no pedido de início de sessão.
  • Usado para provisionar um token de acesso imediatamente após a autenticação.

Escopos adicionais podem ser adicionados conforme necessário no arquivo Program:

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});

Especifique escopos adicionais com AdditionalScopesToConsent:

options.ProviderOptions.AdditionalScopesToConsent.Add("{ADDITIONAL SCOPE URI}");

Note

AdditionalScopesToConsent não é capaz de provisionar permissões de usuário delegadas para o Microsoft Graph por meio da interface do usuário de consentimento do Microsoft Entra ID quando um usuário usa pela primeira vez um aplicativo registrado no Microsoft Azure. Para obter mais informações, consulte Utilizar a API Graph com ASP.NET Core Blazor WebAssembly.

Exemplo de escopo de token de acesso padrão:

options.ProviderOptions.DefaultAccessTokenScopes.Add(
    "api://00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");

Para obter mais informações, consulte as seguintes seções do Cenários adicionais artigo:

Modo de início de sessão

Esta seção diz respeito ao aplicativo Client da solução.

A estrutura define como padrão o modo de login pop-up e recorre ao modo de login por redirecionamento se um pop-up não puder ser aberto. Configure o MSAL para usar o modo de login de redirecionamento definindo a propriedade LoginMode do MsalProviderOptions como redirect:

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.LoginMode = "redirect";
});

A configuração padrão é popupe o valor da string não é sensível a maiúsculas.

Arquivo de importação

Esta seção diz respeito ao aplicativo Client da solução.

O namespace Microsoft.AspNetCore.Components.Authorization é disponibilizado em todo o aplicativo por meio do arquivo _Imports.razor:

...
@using Microsoft.AspNetCore.Components.Authorization
...

Página de índice

Esta seção diz respeito ao aplicativo Client da solução.

A página Índice (wwwroot/index.html) inclui um script que define o AuthenticationService em JavaScript. AuthenticationService lida com os detalhes de baixo nível do protocolo OIDC. O aplicativo chama internamente métodos definidos no script para executar as operações de autenticação.

<script src="_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js"></script>

Componente da aplicação

Esta seção diz respeito ao aplicativo Client da solução.

O componente App (App.razor) é semelhante ao componente App encontrado em Blazor Server aplicativos:

  • O componente CascadingAuthenticationState gerencia a exposição do AuthenticationState ao resto do aplicativo.
  • O componente AuthorizeRouteView garante que o usuário atual esteja autorizado a acessar uma determinada página ou renderize o componente RedirectToLogin.
  • O componente RedirectToLogin gerencia o redirecionamento de usuários não autorizados para a página de login.

Devido a alterações na estrutura entre as versões do ASP.NET Core, a marcação Razor para o componente App (App.razor) não é mostrada nesta secção. Para inspecionar a marcação do componente para uma determinada versão, use ou de uma das seguintes abordagens:

  • Crie um aplicativo provisionado para autenticação a partir do modelo de projeto Blazor WebAssembly padrão para a versão do ASP.NET Core que você pretende usar. Inspecione o componente App (App.razor) no aplicativo gerado.

  • Inspecione o componente App (App.razor) na fonte de referência . Selecione a versão no seletor de ramificação e procure o componente na pasta ProjectTemplates do repositório porque a localização do componente App mudou ao longo dos anos.

    Note

    Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Componente RedirectToLogin

Esta seção diz respeito ao aplicativo Client da solução.

O componente RedirectToLogin (RedirectToLogin.razor):

  • Gerencia o redirecionamento de usuários não autorizados para a página de login.
  • A URL atual que o utilizador está tentando acessar é mantida para que o utilizador possa voltar a essa página se a autenticação for bem-sucedida usando:

Inspecione o componente RedirectToLogin na fonte de referência . A localização do componente mudou ao longo do tempo, portanto, use as ferramentas de pesquisa do GitHub para localizar o componente.

O caminho de login pode ser personalizado pelo aplicativo (RemoteAuthenticationApplicationPathsOptions.LogInPath, padrões da estrutura (dotnet/aspnetcore fonte de referência)). O componente do RedirectToLogin modelo de projeto usa o caminho de login padrão do authentication/login.

Note

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Se um aplicativo personalizar o caminho de login, siga uma das seguintes abordagens:

  • Corresponder o caminho na cadeia de caracteres codificada RedirectToLogin no componente.

  • Injete RemoteAuthenticationOptions para obter o valor configurado. Por exemplo, adote essa abordagem ao personalizar o caminho com AddApiAuthorizationo . Adicione as seguintes diretivas na parte superior do RedirectToLogin componente:

    @using Microsoft.Extensions.Options
    @inject IOptionsSnapshot<RemoteAuthenticationOptions<ApiAuthorizationProviderOptions>> RemoteOptions
    

    Modifique o redirecionamento do componente no OnInitialized método:

    - Navigation.NavigateToLogin("authentication/login");
    + Navigation.NavigateToLogin(RemoteOptions.Get(Options.DefaultName)
    +     .AuthenticationPaths.LogInPath);
    

    Note

    Se outros caminhos forem diferentes dos caminhos padrão do modelo de projeto ou da estrutura, eles deverão ser gerenciados da mesma maneira.

Componente LoginDisplay

Esta seção diz respeito ao aplicativo Client da solução.

O componente LoginDisplay (LoginDisplay.razor) é processado no componente MainLayout (MainLayout.razor) e gerencia os seguintes comportamentos:

  • Para utilizadores autenticados:
    • Exibe o nome de usuário atual.
    • Oferece um link para a página de perfil do usuário no ASP.NET Core Identity.
    • Oferece um botão para sair do aplicativo.
  • Para utilizadores anónimos:
    • Oferece a opção de registo.
    • Oferece a opção de iniciar sessão.

Devido a alterações na estrutura de trabalho nas versões do ASP.NET Core, a marcação Razor para o componente LoginDisplay não é apresentada nesta seção. Para inspecionar a marcação do componente para uma determinada versão, use ou de uma das seguintes abordagens:

  • Crie um aplicativo provisionado para autenticação a partir do modelo de projeto Blazor WebAssembly padrão para a versão do ASP.NET Core que você pretende usar. Inspecione o componente LoginDisplay no aplicativo gerado.

  • Inspecione o componente LoginDisplay na fonte de referência . A localização do componente mudou ao longo do tempo, portanto, use as ferramentas de pesquisa do GitHub para localizar o componente. O conteúdo modelado para Hosted igual a true é utilizado.

    Note

    Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Componente de autenticação

Esta seção diz respeito ao aplicativo Client da solução.

A página produzida pelo componente Authentication (Pages/Authentication.razor) define as rotas necessárias para lidar com diferentes estágios de autenticação.

O componente RemoteAuthenticatorView:

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="@Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

Note

Tipos de referência anuláveis (NRTs) e análise estática de estado nulo do compilador .NET são suportados no ASP.NET Core no .NET 6 ou posterior. Antes do lançamento do ASP.NET Core no .NET 6, o tipo string aparece sem a designação de tipo nulo (?).

Componente FetchData

Esta seção diz respeito ao aplicativo Client da solução.

O componente FetchData mostra como:

  • Provisionar um token de acesso.
  • Use o token de acesso para chamar uma API de recurso protegida na aplicação Server.

A diretiva @attribute [Authorize] indica ao sistema de autorização Blazor WebAssembly que o usuário deve ser autorizado para visitar este componente. A presença do atributo no aplicativo Client não impede que a API no servidor seja chamada sem as credenciais adequadas. A aplicação Server também deve usar [Authorize] nos endpoints apropriados para protegê-los corretamente.

IAccessTokenProvider.RequestAccessToken se encarrega de solicitar um token de acesso que pode ser adicionado à solicitação para chamar a API. Se o token for armazenado em cache ou se o serviço for capaz de provisionar um novo token de acesso sem interação do usuário, a solicitação de token será bem-sucedida. Caso contrário, a solicitação de token falhará com um AccessTokenNotAvailableException, que é interceptado numa instrução try-catch.

Para obter o token real a ser incluído na solicitação, o aplicativo deve verificar se a solicitação foi bem-sucedida chamando tokenResult.TryGetToken(out var token).

Se a solicitação foi bem-sucedida, a variável de token é preenchida com o token de acesso. A propriedade AccessToken.Value do token expõe a cadeia de caracteres literal a ser incluída no cabeçalho da solicitação Authorization.

Se o token não puder ser provisionado sem a interação do usuário, resultando em uma solicitação com falha:

  • ASP.NET Core no .NET 7 ou posterior: o aplicativo navega até AccessTokenResult.InteractiveRequestUrl usando o AccessTokenResult.InteractionOptions fornecido para permitir a atualização do token de acesso.
  • ASP.NET Core no .NET 6 ou anterior: o resultado do token contém uma URL de redirecionamento. Navegar para este URL leva o usuário para a página de login e de volta para a página atual após uma autenticação bem-sucedida.
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using {APP NAMESPACE}.Shared
@attribute [Authorize]
@inject HttpClient Http

...

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
    }
}

Uso de um locatário B2C do Azure Ative Directory

Se a aplicação estiver registada num inquilino Azure Active Directory B2C, tal como descrito em Tutorial: Criar um inquilino do Azure Active Directory B2C, mas seguir as orientações neste artigo, o URI da ID da Aplicação é gerido de forma diferente pelo ME-ID.

Você pode verificar o tipo de locatário de um locatário existente selecionando o link Gerenciar locatários na parte superior do ME-ID organização Visão geral. Examine o valor da coluna do tipo de locatário para a organização. Esta seção refere-se a aplicativos que seguem as orientações deste artigo, mas que estão registrados em um locatário Azure Active Directory B2C.

Em vez de o URI da ID do Aplicativo corresponder ao formato api://{SERVER API APP CLIENT ID OR CUSTOM VALUE}, o URI da ID do Aplicativo tem o formato https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}. Essa diferença afeta as configurações do aplicativo Client e Server.

  • Para o aplicativo de API do servidor, defina o Audience no arquivo de configurações do aplicativo (appsettings.json) para corresponder ao público do aplicativo (URI da ID do Aplicativo) fornecido pelo portal do Azure sem barra à direita:

    "Audience": "https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}"
    

    Example:

    "Audience": "https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444"
    
  • No arquivo Program do aplicativo Client, defina o público do escopo (URI de ID do aplicativo) para corresponder ao público do aplicativo de API do servidor:

    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}/{DEFAULT SCOPE}");
    

    No escopo anterior, o URI/audiência da ID do Aplicativo é a parte https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE} do valor, que não inclui uma barra à direita (/) e não inclui o nome do escopo ({DEFAULT SCOPE}).

    Example:

    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");
    

    No escopo anterior, o URI/audiência da ID do Aplicativo é a parte https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444 do valor, que não inclui uma barra à direita (/) e não inclui o nome do escopo (API.Access).

Uso de um URI de ID de aplicativo personalizado

Se o URI da ID do Aplicativo for um valor personalizado, você deverá atualizar manualmente o URI do escopo do token de acesso padrão no aplicativo Client e adicionar o público à configuração ME-ID do aplicativo Server.

Important

A configuração a seguir não é necessária ao usar o URI de ID de Aplicativo padrão do api://{SERVER API APP CLIENT ID}.

Exemplo de URI de ID de aplicação de urn://custom-app-id-uri e de um nome de escopo de API.Access:

  • No arquivo Program do aplicativo Client:

    options.ProviderOptions.DefaultAccessTokenScopes.Add(
        "urn://custom-app-id-uri/API.Access");
    
  • Em appsettings.json do aplicativo Server, adicione uma entrada Audience com apenas URI da ID do aplicativo e sem barra à direita:

    "Audience": "urn://custom-app-id-uri"
    

Troubleshoot

Logging

Para habilitar o log de depuração ou rastreamento para Blazor WebAssembly autenticação, consulte a seção Log de autenticação do lado do cliente do log do ASP.NET Core Blazor com o seletor de versão do artigo definido como ASP.NET Core no .NET 7 ou posterior.

Erros comuns

  • Configuração incorreta do aplicativo ou do provedor de Identity (IP)

    Os erros mais comuns são causados por configuração incorreta. Seguem-se alguns exemplos:

    • Dependendo dos requisitos do cenário, uma autoridade, instância, ID do locatário, domínio do locatário, ID do cliente ou URI de redirecionamento ausente ou incorreto impede que um aplicativo autentique clientes.
    • Escopos de solicitação incorretos impedem que os clientes acessem os pontos de extremidade da API web do servidor.
    • Permissões incorretas ou ausentes da API do servidor impedem que os clientes acedam aos endpoints da API web do servidor.
    • Executar a aplicação numa porta diferente da configurada na URI de Redirecionamento do registo da aplicação IP. Observe que uma porta não é necessária para o Microsoft Entra ID e um aplicativo em execução em um endereço de teste de desenvolvimento localhost, mas a configuração de porta do aplicativo e a porta onde o aplicativo está sendo executado devem corresponder para endereços nãolocalhost.

    As seções de configuração das diretrizes deste artigo mostram exemplos da configuração correta. Verifique cuidadosamente cada seção do artigo procurando por configuração incorreta de aplicativos e IP.

    Se a configuração parecer correta:

    • Analise os logs do aplicativo.

    • Examine o tráfego de rede entre o aplicativo cliente e o aplicativo IP ou servidor com as ferramentas de desenvolvedor do navegador. Muitas vezes, uma mensagem de erro exata ou uma mensagem com uma pista do que está causando o problema é retornada ao cliente pelo IP ou aplicativo de servidor depois de fazer uma solicitação. A orientação das ferramentas de desenvolvedor pode ser encontrada nos seguintes artigos:

    • Para versões de Blazor em que um JSON Web Token (JWT) é usado, decodifice o conteúdo do token usado para autenticar um cliente ou acessar uma API da Web do servidor, dependendo de onde o problema está ocorrendo. Para obter mais informações, consulte Inspecione o conteúdo de um JSON Web Token (JWT).

    A equipa de documentação responde a feedback sobre documentos e problemas em artigos (abra um problema na secção de comentários Esta página), mas não conseguem fornecer suporte ao produto. Vários fóruns públicos de suporte estão disponíveis para ajudar na solução de problemas de um aplicativo. Recomendamos o seguinte:

    Os fóruns anteriores não pertencem nem são controlados pela Microsoft.

    Para relatórios de bugs de estrutura reproduzíveis que não estejam relacionados à segurança, não sejam sensíveis nem confidenciais, abra um problema com a unidade de produto ASP.NET Core. Não abra um problema com a unidade de produto até que você tenha investigado completamente a causa de um problema e não possa resolvê-lo sozinho e com a ajuda da comunidade em um fórum de suporte público. A unidade de produto não é capaz de solucionar problemas de aplicativos individuais que estão quebrados devido a simples erros de configuração ou casos de uso envolvendo serviços de terceiros. Se um relatório for de natureza sensível ou confidencial ou descrever uma possível falha de segurança no produto que os ciberatacantes podem explorar, consulte Relatando problemas de segurança e bugs (dotnet/aspnetcore repositório GitHub).

  • Cliente não autorizado para ME-ID

    info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] A autorização falhou. Estes requisitos não foram atendidos: DenyAnonymousAuthorizationRequirement: Requer um usuário autenticado.

    Erro ao retornar a chamada de login do ME-ID:

    • Erro: unauthorized_client
    • Descrição: AADB2C90058: The provided application is not configured to allow public clients.

    Para resolver o erro:

    1. No portal do Azure, acesse o manifesto do aplicativo .
    2. Defina o atributo allowPublicClient como null ou true.

Cookies e dados do site

Os cookies e os dados do site podem persistir nas atualizações do aplicativo e interferir nos testes e na solução de problemas. Desmarque o seguinte ao fazer alterações no código do aplicativo, alterações na conta do usuário com o provedor ou alterações na configuração do aplicativo do provedor:

  • Cookies de sessão de utilizador
  • Cookies de aplicações
  • Dados do site em cache e armazenados

Uma abordagem para evitar que cookies persistentes e dados do site interfiram com testes e solução de problemas é:

  • Configurar um navegador
    • Utiliza um navegador para testar de forma que possas configurar para excluir todos os dados cookie e de site sempre que o fechares.
    • Verifique se o navegador está fechado manualmente ou pelo IDE para qualquer alteração na configuração do aplicativo, do usuário de teste ou do provedor.
  • Use um comando personalizado para abrir um navegador no modo InPrivate ou de navegação anônima no Visual Studio:
    • Abra a caixa de diálogo Procurar com através do botão Executar do Visual Studio.
    • Selecione o botão Adicionar.
    • Forneça o caminho para o seu navegador no campo Programa. Os seguintes caminhos executáveis são locais de instalação típicos para o Windows 10. Se o seu navegador estiver instalado em um local diferente ou você não estiver usando o Windows 10, forneça o caminho para o executável do navegador.
      • Microsoft Edge: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
      • Google Chrome: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
      • Mozilla Firefox: C:\Program Files\Mozilla Firefox\firefox.exe
    • No campo de Argumentos , forneça a opção de linha de comando que o navegador usa para abrir no modo InPrivate ou Incógnito. Alguns navegadores exigem o URL do aplicativo.
      • Microsoft Edge: Utilize -inprivate.
      • Google Chrome: Use --incognito --new-window {URL}, onde o placeholder {URL} é o URL a abrir (por exemplo, https://localhost:5001).
      • Mozilla Firefox: Utilize -private -url {URL}, onde o marcador {URL} representa o URL a ser aberto (por exemplo, https://localhost:5001).
    • Forneça um nome no campo Nome amigável. Por exemplo, Firefox Auth Testing.
    • Selecione o botão OK.
    • Para evitar ter de selecionar o perfil do navegador para cada iteração de teste com uma aplicação, defina o perfil como padrão com o botão Definir como Padrão.
    • Certifique-se de que o navegador está fechado pelo IDE para qualquer alteração na configuração do aplicativo, usuário de teste ou provedor.

Atualizações de aplicativos

Um aplicativo em funcionamento pode falhar imediatamente após atualizar o SDK do .NET na máquina de desenvolvimento ou alterar as versões do pacote dentro do aplicativo. Em alguns casos, pacotes incoerentes podem quebrar um aplicativo ao executar grandes atualizações. A maioria desses problemas pode ser corrigida seguindo estas instruções:

  1. Limpe os caches de pacotes NuGet do sistema local executando dotnet nuget locals all --clear a partir de um shell de comando.
  2. Exclua as pastas bin e obj do projeto.
  3. Restaure e reconstrua o projeto.
  4. Exclua todos os arquivos na pasta de implantação no servidor antes de reimplantar o aplicativo.

Note

Não há suporte para o uso de versões de pacote incompatíveis com a estrutura de destino do aplicativo. Para obter informações acerca de um pacote, utilize a Galeria NuGet.

Executar o aplicativo Server

Ao testar e resolver problemas de uma solução hospedada Blazor WebAssembly, certifique-se de estar a executar a aplicação a partir do projeto Server.

Inspecionar o usuário

O componente User a seguir pode ser usado diretamente em aplicativos ou servir como base para personalização adicional.

User.razor:

@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService

<h1>@AuthenticatedUser?.Identity?.Name</h1>

<h2>Claims</h2>

@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
    <p class="claim">@(claim.Type): @claim.Value</p>
}

<h2>Access token</h2>

<p id="access-token">@AccessToken?.Value</p>

<h2>Access token claims</h2>

@foreach (var claim in GetAccessTokenClaims())
{
    <p>@(claim.Key): @claim.Value.ToString()</p>
}

@if (AccessToken != null)
{
    <h2>Access token expires</h2>

    <p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
    <p id="access-token-expires">@AccessToken.Expires</p>

    <h2>Access token granted scopes (as reported by the API)</h2>

    @foreach (var scope in AccessToken.GrantedScopes)
    {
        <p>Scope: @scope</p>
    }
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationState { get; set; }

    public ClaimsPrincipal AuthenticatedUser { get; set; }
    public AccessToken AccessToken { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        var state = await AuthenticationState;
        var accessTokenResult = await AuthorizationService.RequestAccessToken();

        if (!accessTokenResult.TryGetToken(out var token))
        {
            throw new InvalidOperationException(
                "Failed to provision the access token.");
        }

        AccessToken = token;

        AuthenticatedUser = state.User;
    }

    protected IDictionary<string, object> GetAccessTokenClaims()
    {
        if (AccessToken == null)
        {
            return new Dictionary<string, object>();
        }

        // header.payload.signature
        var payload = AccessToken.Value.Split(".")[1];
        var base64Payload = payload.Replace('-', '+').Replace('_', '/')
            .PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');

        return JsonSerializer.Deserialize<IDictionary<string, object>>(
            Convert.FromBase64String(base64Payload));
    }
}

Inspecionar o conteúdo de um JSON Web Token (JWT)

Para decodificar um JSON Web Token (JWT), utilize a ferramenta jwt.ms disponibilizada pela Microsoft. Os valores na interface do usuário nunca saem do navegador.

Exemplo de JWT codificado (abreviado para exibição):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Exemplo de JWT decodificado pela ferramenta para um aplicativo que se autentica no Azure AAD B2C:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
  "sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
  "aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

Recursos adicionais