Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Implante APIs da Web ASP.NET Core protegidas por Microsoft.Identity.Web por trás dos gateways de API e proxies reversos do Azure, incluindo Gerenciamento de API do Azure (APIM), Azure Front Door e Gateway de Aplicativo do Azure.
Entender os requisitos do gateway
Ao implantar APIs protegidas por trás de gateways, você deve lidar com várias preocupações:
- Cabeçalhos encaminhados – Preservar o contexto original da solicitação (esquema, host, IP)
- Validação de token – Garantir que as declarações de audiência correspondam às URLs do gateway
- Configuração do CORS – Manipular solicitações entre origens corretamente
- Pontos de extremidade de integridade – Fornecer verificações de integridade não autenticadas
- Roteamento baseado em caminho – suporte a prefixos de caminho no nível do gateway
- Terminação SSL/TLS – Manipular HTTPS corretamente quando o gateway encerrar o SSL
Analisar cenários comuns de gateway
Escolha um gateway com base em seus requisitos. As seções a seguir descrevem os serviços de gateway de Azure mais comuns para APIs protegidas.
APIM (Gerenciamento de API do Azure)
Caso de uso: Gateway de API Empresarial com políticas, limitação de taxa, transformação
Arquitetura:
Client → Microsoft Entra ID → Token
Client → APIM (apim.azure-api.net) → Backend API (app.azurewebsites.net)
Principais considerações:
- As políticas APIM podem validar tokens JWT antes de encaminhar para o backend
- A API de back-end ainda valida tokens
- A declaração de destinatário deve corresponder à URL do APIM ou à URL do backend (configurar conforme necessário)
Azure Front Door
Caso de uso: Balanceamento de carga global, CDN, proteção contra DDoS
Arquitetura:
Client → Microsoft Entra ID → Token
Client → Front Door (azurefd.net) → Backend API (regional endpoints)
Principais considerações:
- O Front Door encaminha solicitações com
X-Forwarded-*cabeçalhos - Terminação SSL/TLS no Front Door
- A validação de audiência de token precisa de configuração
Gateway de Aplicativo do Azure
Caso de uso: Balanceamento de carga regional, WAF, roteamento baseado em caminho
Arquitetura:
Client → Microsoft Entra ID → Token
Client → Application Gateway → Backend API (multiple instances)
Principais considerações:
- integração do WAF (Firewall de Aplicativo Web)
- Regras de roteamento baseadas em rotas
- Sondas de integridade do back-end precisam de endpoints não autenticados
Configurar padrões comuns
Aplique esses padrões de configuração para garantir que sua API protegida funcione corretamente por trás de qualquer gateway.
1. Middleware de cabeçalhos encaminhados
Sempre configure o middleware de cabeçalhos redirecionados quando estiver atrás de um gateway. O código a seguir registra o middleware e o define para ser executado antes da autenticação:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
// Configure forwarded headers BEFORE authentication
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
// Clear known networks/proxies to accept forwarded headers from any source
// (Azure infrastructure will be the proxy)
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
// Limit to specific headers if needed
options.ForwardedForHeaderName = "X-Forwarded-For";
options.ForwardedProtoHeaderName = "X-Forwarded-Proto";
options.ForwardedHostHeaderName = "X-Forwarded-Host";
});
// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
var app = builder.Build();
// USE forwarded headers BEFORE authentication middleware
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.Run();
O middleware de cabeçalhos encaminhados é crítico porque:
- Preserva o endereço IP do cliente original para registro em log
-
HttpContext.Request.SchemeGarante que reflita o esquema HTTPS original - Fornece o cabeçalho correto
Hostpara URLs de redirecionamento e validação de token
2. Configuração de público-alvo de token
Opção A: aceitar URLs de gateway e back-end
Adicione vários públicos válidos em sua appsettings.json configuração:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"Audience": "api://your-client-id",
"TokenValidationParameters": {
"ValidAudiences": [
"api://your-client-id",
"https://your-backend.azurewebsites.net",
"https://your-apim.azure-api.net"
]
}
}
}
Como alternativa, configure vários públicos programaticamente em Program.cs:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
// Customize token validation to accept multiple audiences
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingValidation = options.TokenValidationParameters.AudienceValidator;
options.TokenValidationParameters.AudienceValidator = (audiences, token, parameters) =>
{
var validAudiences = new[]
{
"api://your-client-id",
"https://your-backend.azurewebsites.net",
"https://your-apim.azure-api.net",
builder.Configuration["AzureAd:ClientId"] // Also accept ClientId
};
return audiences.Any(a => validAudiences.Contains(a, StringComparer.OrdinalIgnoreCase));
};
});
Opção B: reescrever o público-alvo na política do APIM
Configure o APIM para validar a declaração de audiência antes de encaminhar para o back-end:
<policies>
<inbound>
<validate-jwt header-name="Authorization" failed-validation-httpcode="401">
<openid-config url="https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>api://your-client-id</audience>
</audiences>
</validate-jwt>
<!-- Optionally modify token claims for backend -->
<set-header name="X-Gateway-Validated" exists-action="override">
<value>true</value>
</set-header>
</inbound>
</policies>
3. Configuração do ponto de extremidade de saúde
Os gateways exigem endpoints de saúde não autenticados para sondas. Mapeie um endpoint de saúde antes do middleware de autenticação para contornar a validação de token.
var app = builder.Build();
// Health endpoint BEFORE authentication middleware
app.MapGet("/health", () => Results.Ok(new { status = "healthy" }))
.AllowAnonymous();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
// Protected endpoints require authentication
app.MapControllers();
app.Run();
Como alternativa, use a estrutura interna de Verificações de Saúde do ASP.NET Core para relatórios de saúde mais completos.
using Microsoft.Extensions.Diagnostics.HealthChecks;
builder.Services.AddHealthChecks()
.AddCheck("api", () => HealthCheckResult.Healthy());
var app = builder.Build();
app.MapHealthChecks("/health").AllowAnonymous();
app.MapHealthChecks("/ready").AllowAnonymous();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
4. Configuração do CORS por trás de gateways
Ao usar Azure Front Door ou APIM com aplicativos de front-end, configure o CORS para permitir solicitações das origens dos seus gateways:
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowGateway", policy =>
{
policy.WithOrigins(
"https://your-apim.azure-api.net",
"https://your-frontend.azurefd.net",
"https://your-app.azurewebsites.net"
)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // If using cookies
});
});
var app = builder.Build();
app.UseForwardedHeaders();
app.UseCors("AllowGateway");
app.UseAuthentication();
app.UseAuthorization();
app.Run();
Importante
O CORS deve ser configurado após cabeçalhos encaminhados e antes da autenticação.
Integrar com Gerenciamento de API do Azure
Esta seção fornece a configuração completa para implantar uma API protegida por trás de Gerenciamento de API do Azure.
Configurar a API de back-end
Configure cabeçalhos de encaminhamento e autenticação Microsoft Entra ID em Program.cs:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Forwarded headers for APIM
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
// Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllers();
var app = builder.Build();
// Middleware order matters
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Adicione a configuração de Microsoft Entra a appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-backend-api-client-id",
"Audience": "api://your-backend-api-client-id"
}
}
Adicionar política de entrada no APIM para validação de JWT
Defina uma política de entrada que valide o token JWT, aplique a limitação de taxa e encaminhe a solicitação para o back-end:
<policies>
<inbound>
<base />
<!-- Validate JWT token -->
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
<openid-config url="https://login.microsoftonline.com/{your-tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>api://your-backend-api-client-id</audience>
</audiences>
<issuers>
<issuer>https://login.microsoftonline.com/{your-tenant-id}/v2.0</issuer>
</issuers>
<required-claims>
<claim name="scp" match="any">
<value>access_as_user</value>
</claim>
</required-claims>
</validate-jwt>
<!-- Rate limiting -->
<rate-limit calls="100" renewal-period="60" />
<!-- Forward original host header -->
<set-header name="X-Forwarded-Host" exists-action="override">
<value>@(context.Request.OriginalUrl.Host)</value>
</set-header>
<!-- Forward to backend -->
<set-backend-service base-url="https://your-backend.azurewebsites.net" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Configurar configurações da API do APIM
Use os seguintes valores nomeados e configurações de API para concluir a configuração do APIM:
Valores nomeados (para reutilização):
-
tenant-id: sua ID de locatário Microsoft Entra -
backend-api-client-id: ID do cliente da API de back-end -
backend-base-url:https://your-backend.azurewebsites.net
Configurações da API:
-
Sufixo de URL da API:
/api(prefixo de caminho opcional) - URL do serviço Web: definir por meio da política usando valores nomeados
- Assinatura necessária: Sim (adiciona outra camada de segurança)
Configurar o aplicativo do cliente
Os aplicativos cliente solicitam tokens para a API de back-end, não o APIM. O código a seguir adquire um token e chama a API por meio do ponto de extremidade APIM:
// Client app requests token
var result = await app.AcquireTokenSilent(
scopes: new[] { "api://your-backend-api-client-id/access_as_user" },
account)
.ExecuteAsync();
// Call APIM URL with token
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Add APIM subscription key
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "your-subscription-key");
var response = await client.GetAsync("https://your-apim.azure-api.net/api/weatherforecast");
Integrar com Azure Front Door
Configure sua API protegida para distribuição global por trás de Azure Front Door.
Configurar a API de back-end
Configure os cabeçalhos encaminhados para o serviço Azure Front Door em Program.cs:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
// Configure for Azure Front Door
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
// Accept headers from any source (Azure Front Door)
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
// Front Door specific headers
options.ForwardedForHeaderName = "X-Forwarded-For";
options.ForwardedProtoHeaderName = "X-Forwarded-Proto";
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
var app = builder.Build();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Configurar origens do Front Door
Conclua as seguintes etapas no portal Azure para configurar a origem do Front Door:
- Criar perfil do Front Door
- Adicione o grupo de origem com as suas instâncias da API de back-end
- Configurar sondas de saúde no
/healthponto de extremidade - Definir somente o encaminhamento HTTPS
- Habilitar a política do WAF (opcional)
Configurações de sonda de integridade:
-
Caminho:
/health - Protocolo: HTTPS
- Método: GET
- Intervalo: 30 segundos
Gerenciar várias regiões
Ao implantar em várias regiões por trás do Front Door, adicione reconhecimento de região para registro em log e diagnóstico:
// Add region awareness for logging/diagnostics
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
app.Use(async (context, next) =>
{
// Log the actual client IP and region
var clientIp = context.Connection.RemoteIpAddress?.ToString();
var forwardedFor = context.Request.Headers["X-Forwarded-For"].ToString();
var frontDoorId = context.Request.Headers["X-Azure-FDID"].ToString();
// Add to logger scope or response headers
context.Response.Headers.Add("X-Served-By-Region",
builder.Configuration["Region"] ?? "unknown");
await next();
});
Validar tokens com o Front Door
Se os clientes solicitarem tokens com escopo para a URL do Front Door, adicione à lista de audiências válidas:
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.ValidAudiences = new[]
{
"api://your-backend-api-client-id",
"https://your-frontend.azurefd.net", // Front Door URL
builder.Configuration["AzureAd:ClientId"]
};
});
Integrar com o Gateway de Aplicativo do Azure
Configure sua API protegida por trás do Gateway de Aplicativo do Azure com suporte ao Firewall de Aplicativo Web (WAF).
Configurar a API de back-end
Configurar cabeçalhos encaminhados para o Gateway de Aplicação em Program.cs:
using Microsoft.AspNetCore.HttpOverrides;
var builder = WebApplication.CreateBuilder(args);
// Application Gateway uses standard forwarded headers
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddHealthChecks();
var app = builder.Build();
// Health endpoint for Application Gateway probes
app.MapHealthChecks("/health").AllowAnonymous();
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Definir configurações do Gateway de Aplicativo
Defina as seguintes configurações de back-end, investigação de integridade e WAF no portal Azure:
Configurações de back-end:
- Protocolo: HTTPS (recomendado) ou HTTP
- Porta: 443 ou 80
- Override backend path: Não (exceto se necessário)
-
Sonda personalizada: Sim, apontando para
/health
Sonda de Saúde:
- Protocolo: HTTPS ou HTTP
- Host: deixe o padrão ou especifique
-
Caminho:
/health - Intervalo: 30 segundos
- Limite insalubre: 3
Política do WAF:
- Habilitar o WAF com o conjunto de regras OWASP 3.2
-
Importante: verifique se os tokens JWT em
Authorizationcabeçalhos não estão bloqueados - Talvez seja necessário criar exclusões de WAF para
RequestHeaderNamesconter "Autorização"
Configurar o roteamento baseado em caminho
Ao usar regras de roteamento baseadas em caminho, configure sua API de back-end para lidar com o prefixo de caminho:
// Backend API should work regardless of path prefix
var app = builder.Build();
// Option 1: Use path base (if gateway adds prefix)
app.UsePathBase("/api/v1");
// Option 2: Configure routing explicitly
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Regra do Gateway de Aplicativo:
-
Caminho:
/api/v1/* - Destino de back-end: seu pool de back-end
- Configurações de back-end: usar configurações definidas
Solucionar problemas comuns
Use essas soluções para resolver os problemas mais comuns ao implantar APIs protegidas por trás de gateways.
Problema: 401 Não autorizado após a implantação atrás do gateway
Sintomas:
- O API funciona localmente, mas retorna 401 por trás do gateway
- O token parece válido quando decodificado em jwt.ms
Causas possíveis::
Incompatibilidade de declarações de audiência
# Check token audience # Decode token and verify 'aud' claim matches one of: # - api://your-client-id # - https://your-backend.azurewebsites.net # - https://your-gateway-urlMiddleware de cabeçalhos encaminhados ausentes
// Ensure this is BEFORE authentication app.UseForwardedHeaders(); app.UseAuthentication();Problemas de redirecionamento HTTPS
// If gateway terminates SSL, may need to disable or configure carefully if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Solution:
- Habilitar o registro em log de depuração para ver os detalhes da validação de token
- Adicionar várias audiências válidas na validação de token
-
X-Forwarded-*Verifique se os cabeçalhos são encaminhados pelo gateway
Problema: falhas nas sondas de saúde
Sintomas:
- O gateway marca o back-end como não saudável
- O endpoint de saúde retorna 401
Solution:
Certifique-se de que o endpoint de saúde seja executado antes do middleware de autenticação.
// Ensure health endpoint is BEFORE authentication
app.MapHealthChecks("/health").AllowAnonymous();
// Alternative: Use custom middleware
app.Map("/health", healthApp =>
{
healthApp.Run(async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("healthy");
});
});
app.UseAuthentication(); // Health endpoint bypasses this
Problema: erros de CORS no Front Door
Sintomas:
- As solicitações opções de pré-vôo falham
- O console do navegador mostra erros de CORS
Solution:
Adicione as origens do Front Door e do front-end à política CORS:
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.WithOrigins(
"https://your-frontend.azurefd.net",
"https://your-app.com"
)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
var app = builder.Build();
app.UseForwardedHeaders();
app.UseCors(); // Before authentication
app.UseAuthentication();
app.UseAuthorization();
Problema: avisos de "cabeçalho encaminhado" em logs
Sintomas:
Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware: Unknown proxy
Solution:
Limpe as redes e proxies conhecidos para aceitar cabeçalhos encaminhados da infraestrutura Azure:
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
// Clear known networks to accept from any proxy
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
// Or explicitly add Azure IP ranges (more secure but complex)
// options.KnownProxies.Add(IPAddress.Parse("20.x.x.x"));
});
Problema: APIM retorna 401, mas back-end retorna 200
Sintomas:
- O token é válido para o back-end
- Falha na política do APIM
validate-jwt
Solution:
Verifique se o público de política do APIM corresponde ao público-alvo do token:
<validate-jwt header-name="Authorization">
<openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" />
<audiences>
<!-- Must match the 'aud' claim in your token -->
<audience>api://your-backend-api-client-id</audience>
</audiences>
</validate-jwt>
Problema: conflito de vários esquemas de autenticação
Sintomas:
- Usando tanto portador de token JWT quanto outros esquemas de autenticação
- O esquema errado está selecionado
Solution:
Especifique o esquema de autenticação explicitamente no controlador:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.AddScheme<MyCustomOptions, MyCustomHandler>("CustomScheme", options => {});
// In controller, specify scheme explicitly
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class WeatherForecastController : ControllerBase
{
// ...
}
Seguir as práticas recomendadas
Aplique essas práticas para criar uma implantação de API segura e resiliente por trás de gateways.
1. Defesa em profundidade
Sempre valide tokens na API de back-end, mesmo que o gateway os valide:
// Gateway validates token (APIM policy)
// Backend ALSO validates token (Microsoft.Identity.Web)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
A configuração do gateway pode ser alterada e os tokens podem ser reutilizados. A defesa em profundidade é essencial para a segurança.
2. Usar identidades gerenciadas para comunicação de gateway para back-end
Se o gateway chamar o back-end com sua identidade própria, configure o back-end para aceitar tokens de usuário e tokens de identidade gerenciados.
// Backend accepts both user tokens and gateway's managed identity
builder.Services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.ValidAudiences = new[]
{
"api://backend-api-client-id", // User tokens
"https://management.azure.com" // Managed identity tokens (if applicable)
};
});
3. Monitorar métricas de gateway
Acompanhe estas principais métricas para manter a visibilidade da implantação do gateway:
- Taxas de erro 401/403
- Falhas de validação de token
- Falhas de sondas de saúde
- Cabeçalhos encaminhados (para depuração)
Passo 4: Usar o Application Insights
Adicione a telemetria do Application Insights para registrar propriedades de solicitações específicas do gateway:
builder.Services.AddApplicationInsightsTelemetry();
// Log custom properties
app.Use(async (context, next) =>
{
var telemetry = context.RequestServices.GetRequiredService<TelemetryClient>();
telemetry.TrackEvent("ApiRequest", new Dictionary<string, string>
{
["ForwardedFor"] = context.Request.Headers["X-Forwarded-For"],
["OriginalHost"] = context.Request.Headers["X-Forwarded-Host"],
["Gateway"] = "APIM" // or "FrontDoor", "AppGateway"
});
await next();
});
5. Separar a integridade do pronto
Use pontos de extremidade distintos para verificar a vivacidade (o serviço está em execução?) e a prontidão (o serviço pode aceitar tráfego?).
// Health: Is the service running?
app.MapGet("/health", () => Results.Ok()).AllowAnonymous();
// Ready: Can the service accept traffic?
app.MapHealthChecks("/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("ready")
}).AllowAnonymous();
builder.Services.AddHealthChecks()
.AddCheck("database", () => /* check DB */ , tags: new[] { "ready" })
.AddCheck("cache", () => /* check cache */ , tags: new[] { "ready" });
6. Documentar a configuração do gateway
Crie uma página README ou wiki que documente:
- Quais gateways estão em uso
- Expectativas da audiência sobre tokens
- Configuração do CORS
- Pontos de extremidade de verificação de saúde
- Configuração de cabeçalhos de encaminhamento
- Procedimentos de reversão de emergência
Criar um exemplo completo com Gerenciamento de API do Azure
Esta seção fornece um exemplo completo e pronto para produção de uma API ASP.NET Core por trás de Gerenciamento de API do Azure com autenticação Microsoft Entra ID.
API de back-end (ASP.NET Core)
O Program.cs a seguir configura cabeçalhos encaminhados, autenticação do Microsoft Entra, verificações de integridade e Application Insights:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
// Forwarded headers for APIM
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.All;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
// Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph()
.AddInMemoryTokenCaches();
// Application Insights
builder.Services.AddApplicationInsightsTelemetry();
// Health checks
builder.Services.AddHealthChecks();
builder.Services.AddControllers();
var app = builder.Build();
// Health endpoint (unauthenticated)
app.MapHealthChecks("/health").AllowAnonymous();
// Middleware order is critical
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Adicione a seguinte configuração do Microsoft Entra e do Application Insights ao appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "backend-api-client-id",
"Audience": "api://backend-api-client-id"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Identity.Web": "Debug"
}
},
"ApplicationInsights": {
"ConnectionString": "your-connection-string"
}
}
O controlador a seguir requer autenticação e registra cabeçalhos encaminhados para depuração:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web.Resource;
[Authorize]
[ApiController]
[Route("[controller]")]
[RequiredScope("access_as_user")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IActionResult Get()
{
// Log forwarded headers for debugging
var forwardedFor = HttpContext.Request.Headers["X-Forwarded-For"];
var forwardedHost = HttpContext.Request.Headers["X-Forwarded-Host"];
_logger.LogInformation(
"Request from {ForwardedFor} via {ForwardedHost}",
forwardedFor,
forwardedHost);
return Ok(new[] { "Weather", "Forecast", "Data" });
}
}
Configuração do APIM
A política de entrada a seguir valida tokens JWT, aplica limitação de velocidade, encaminha cabeçalhos e configura CORS.
<policies>
<inbound>
<base />
<!-- Rate limiting per subscription -->
<rate-limit-by-key calls="100" renewal-period="60"
counter-key="@(context.Subscription.Id)" />
<!-- Validate JWT -->
<validate-jwt header-name="Authorization"
failed-validation-httpcode="401"
failed-validation-error-message="Unauthorized">
<openid-config url="https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>api://backend-api-client-id</audience>
</audiences>
<issuers>
<issuer>https://login.microsoftonline.com/{tenant-id}/v2.0</issuer>
</issuers>
<required-claims>
<claim name="scp" match="any">
<value>access_as_user</value>
</claim>
</required-claims>
</validate-jwt>
<!-- Forward headers -->
<set-header name="X-Forwarded-Host" exists-action="override">
<value>@(context.Request.OriginalUrl.Host)</value>
</set-header>
<set-header name="X-Forwarded-Proto" exists-action="override">
<value>@(context.Request.OriginalUrl.Scheme)</value>
</set-header>
<!-- Backend URL -->
<set-backend-service base-url="https://your-backend.azurewebsites.net" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<!-- Add CORS headers if needed -->
<cors>
<allowed-origins>
<origin>https://your-frontend.com</origin>
</allowed-origins>
<allowed-methods>
<method>GET</method>
<method>POST</method>
</allowed-methods>
<allowed-headers>
<header>*</header>
</allowed-headers>
</cors>
</outbound>
<on-error>
<base />
</on-error>
</policies>