Para configurar o código para sua API da Web protegida, entenda:
O que define APIs como protegidas.
Como configurar um token de portador.
Como validar o token.
O que define ASP.NET e ASP.NET APIs principais como protegidas?
Como os aplicativos Web, as APIs Web ASP.NET e ASP.NET Core são protegidas porque suas ações do controlador são prefixadas com o atributo [Autorizar]. As ações do controlador só podem ser chamadas se a API for chamada com uma identidade autorizada.
Considere as perguntas seguintes:
Somente um aplicativo pode chamar uma API da Web. Como a API sabe a identidade do aplicativo que a chama?
Se o aplicativo chamar a API em nome de um usuário, qual é a identidade do usuário?
Token ao portador
O token de portador definido no cabeçalho quando o aplicativo é chamado contém informações sobre a identidade do aplicativo. Ele também contém informações sobre o usuário, a menos que o aplicativo Web aceite chamadas de serviço a serviço de um aplicativo daemon.
Aqui está um exemplo de código C# que mostra um cliente chamando a API depois que ele adquire um token com a Biblioteca de Autenticação da Microsoft para .NET (MSAL.NET):
var scopes = new[] {$"api://.../access_as_user"};
var result = await app.AcquireToken(scopes)
.ExecuteAsync();
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
Importante
Um aplicativo cliente solicita o token de portador para a plataforma de identidade da Microsoft para a API da Web. A API é o único aplicativo que deve verificar o token e exibir as declarações que ele contém. Os aplicativos cliente nunca devem tentar inspecionar as declarações em tokens.
No futuro, a API da Web pode exigir que o token seja criptografado. Esse requisito impediria o acesso de aplicativos cliente que podem exibir tokens de acesso.
Configuração do JwtBearer
Esta seção descreve como configurar um token de portador.
Arquivo de configuração
Você precisa especificar somente TenantId se quiser aceitar tokens de acesso de um único locatário (aplicativo de linha de negócios). Caso contrário, pode ser deixado como common. Os diferentes valores podem ser:
Um GUID (ID do Locatário = ID do Diretório)
common pode ser qualquer organização e contas pessoais
Usando um URI de ID de aplicativo personalizado para uma API da Web
Se você aceitou o URI de ID de Aplicativo padrão proposto pelo portal do Azure, não precisará especificar a audiência (consulte URI de ID de Aplicativo e escopos). Caso contrário, adicione uma Audience propriedade cujo valor seja o URI da ID do Aplicativo para sua API da Web. Isso normalmente começa com api://.
Quando um aplicativo é chamado em uma ação de controlador que contém um atributo [Autorizar], ASP.NET e ASP.NET Core extraem o token de acesso do token de portador do cabeçalho de Autorização. O token de acesso é então encaminhado para o middleware JwtPorter, que chama Microsoft IdentityModel Extensions para .NET.
Microsoft.Identity.Web fornece a cola entre ASP.NET Core, o middleware de autenticação e a Microsoft Authentication Library (MSAL) para .NET. Ele permite uma experiência de desenvolvedor mais clara e robusta e aproveita o poder da plataforma de identidade da Microsoft e do Azure AD B2C.
ASP.NET para .NET 6.0
Para criar um novo projeto de API da Web que usa Microsoft.Identity.Web, use um modelo de projeto na CLI do .NET 6.0 ou Visual Studio.
CLI do núcleo Dotnet
# Create new web API that uses Microsoft.Identity.Web
dotnet new webapi --auth SingleOrg
Visual Studio - Para criar um projeto de API da Web no Visual Studio, selecione Arquivo>Novo>Projeto>ASP.NET API Web Principal.
Os modelos de projeto .NET CLI e Visual Studio criam um arquivo de Program.cs semelhante a esse trecho de código. Aviso Microsoft.Identity.Web usando diretiva e as linhas que contêm autenticação e autorização.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Microsoft.Identity.Web.OWIN fornece a cola entre ASP.NET, o middleware de autenticação ASP.NET e a Biblioteca de Autenticação da Microsoft (MSAL) para .NET. Ele permite uma experiência de desenvolvedor mais clara e robusta e aproveita o poder da plataforma de identidade da Microsoft e do Azure AD B2C.
Ele usa o mesmo arquivo de configuração que ASP.NET Core (appsettings.json) e você precisa se certificar de que esse arquivo é copiado com a saída do seu projeto (cópia de propriedade sempre nas propriedades do arquivo no Visual Studio ou no .csproj)
Microsoft.Identity.Web.OWIN adiciona um método de extensão ao IAppBuilder chamado AddMicrosoftIdentityWebApi. Esse método toma como parâmetro uma instância da OwinTokenAcquirerFactory qual você recebe chamadas OwinTokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>() e que apresenta uma instância à qual você pode adicionar muitos serviços para chamar APIs downstream ou configurar o cache de IServiceCollection token.
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Owin;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web.OWIN;
using System.Web.Services.Description;
namespace OwinWebApp
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
OwinTokenAcquirerFactory factory = TokenAcquirerFactory.GetDefaultInstance<OwinTokenAcquirerFactory>();
app.AddMicrosoftIdentityWebApp(factory);
factory.Services
.Configure<ConfidentialClientApplicationOptions>(options => { options.RedirectUri = "https://localhost:44386/"; })
.AddMicrosoftGraph()
.AddDownstreamApi("DownstreamAPI1", factory.Configuration.GetSection("DownstreamAPI"))
.AddInMemoryTokenCaches();
factory.Build();
}
}
}
--
Validação de token
No trecho anterior, o middleware JwtBearer, como o middleware OpenID Connect em aplicativos Web, valida o token com base no valor de TokenValidationParameters. O token é descriptografado conforme necessário, as declarações são extraídas e a assinatura é verificada. Em seguida, o middleware valida o token verificando estes dados:
Público-alvo: o token é direcionado para a API da Web.
Sub: Foi emitido para um aplicativo que tem permissão para chamar a API da Web.
Emissor: foi emitido por um serviço de token de segurança confiável (STS).
Prazo de validade: A sua vida útil está ao alcance.
Assinatura: Não foi adulterado.
Também pode haver validações especiais. Por exemplo, é possível validar que as chaves de assinatura, quando incorporadas em um token, são confiáveis e que o token não está sendo reproduzido. Finalmente, alguns protocolos requerem validações específicas.
Garante que o token é para o aplicativo que valida o token para você.
ValidateIssuer
Garante que o token foi emitido por um STS confiável, o que significa que é de alguém em quem você confia.
ValidateIssuerSigningKey
Garante que o aplicativo que valida o token confie na chave que foi usada para assinar o token. Há um caso especial em que a chave está incorporada no token. Mas este caso não costuma surgir.
ValidateLifetime
Garante que o token ainda ou já é válido. O validador verifica se o tempo de vida do token está no intervalo especificado pelo notbefore e expira as declarações.
ValidateSignature
Garante que o token não foi adulterado.
ValidateTokenReplay
Garante que o token não seja reproduzido. Há um caso especial para alguns protocolos de uso único.
Personalizando a validação de token
Os validadores estão associados às propriedades da classe TokenValidationParameters . As propriedades são inicializadas a partir da configuração ASP.NET e ASP.NET Core.
Na maioria dos casos, não é necessário alterar os parâmetros. Os aplicativos que não são locatários individuais são exceções. Estas aplicações Web aceitam utilizadores de qualquer organização ou de contas Microsoft pessoais. Neste caso, os emitentes devem ser validados. Microsoft.Identity.Web também cuida da validação do emissor.
No ASP.NET Core, se você quiser personalizar os parâmetros de validação de token, use o seguinte trecho em seu Startup.cs:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration);
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.ValidAudiences = new[] { /* list of valid audiences */};
});
Para ASP.NET MVC, o exemplo de código a seguir mostra como fazer a validação de token personalizado:
Você também pode validar tokens de acesso de entrada no Azure Functions. Você pode encontrar exemplos dessa validação nos seguintes exemplos de código no GitHub: