Nasazení chráněných rozhraní API za branami

Nasaďte webová rozhraní API ASP.NET Core chráněná pomocí Microsoft. Identity.Web za branami rozhraní API Azure a reverzními proxy servery, včetně Azure API Management (APIM), Azure Front Door a Azure Application Gateway.

Vysvětlení požadavků na bránu

Když nasadíte chráněná rozhraní API za brány, musíte řešit několik problémů:

  • Předávané hlavičky – Zachování původního kontextu požadavku (schéma, hostitel, IP adresa)
  • Ověření tokenu – Zajištění, aby deklarace identity cílové skupiny odpovídaly adresám URL brány
  • Konfigurace CORS – Správné zpracování požadavků mezi zdroji
  • Koncové body stavu – Poskytování neověřených kontrol stavu
  • Směrování na základě cest – Podpora předpon cest na úrovni brány
  • Ukončení protokolu SSL/TLS – Správné zacházení s HTTPS při ukončení SSL bránou

Projděte si běžné scénáře brány.

Vyberte bránu na základě vašich požadavků. Následující části popisují nejběžnější služby brány Azure pro chráněná rozhraní API.

Azure API Management (APIM)

Případ použití: Brána podnikového rozhraní API se zásadami, omezováním rychlosti, transformací

Architektura:

Client → Microsoft Entra ID → Token
Client → APIM (apim.azure-api.net) → Backend API (app.azurewebsites.net)

Klíčové aspekty:

  • Zásady APIM můžou ověřit tokeny JWT před předáním do back-endu.
  • Rozhraní API back-endu stále ověřuje tokeny.
  • Deklarace identity cílové skupiny se musí shodovat s adresou URL služby APIM nebo back-endovou adresou URL (odpovídajícím způsobem nakonfigurovat).

Azure Front Door

Případ použití: Globální vyrovnávání zatížení, CDN, ochrana před útoky DDoS

Architektura:

Client → Microsoft Entra ID → Token
Client → Front Door (azurefd.net) → Backend API (regional endpoints)

Klíčové aspekty:

  • Front Door předává požadavky s hlavičkami X-Forwarded-*
  • Ukončení protokolu SSL/TLS ve službě Front Door
  • Ověření cílové skupiny tokenů vyžaduje konfiguraci

Azure Application Gateway

Případ použití: Regionální vyrovnávání zatížení, WAF, směrování na základě cest

Architektura:

Client → Microsoft Entra ID → Token
Client → Application Gateway → Backend API (multiple instances)

Klíčové aspekty:

  • Web Application Firewall (WAF) integrace
  • Pravidla směrování založená na cestě
  • Sondy stavu back-endu vyžadují neověřené koncové body.

Konfigurace běžných vzorů

Použijte tyto vzory konfigurace, abyste zajistili, že vaše chráněné rozhraní API funguje správně za libovolnou bránou.

1. Middleware předávaných hlaviček

Vždy konfigurujte middleware pro přeposílání hlaviček, když je za bránou. Následující kód zaregistruje middleware a nastaví ho tak, aby se spustil před ověřením:

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();

Middleware předávaných hlaviček je zásadní, protože:

  • Zachová původní IP adresu klienta pro protokolování.
  • Zajišťuje, že HttpContext.Request.Scheme zachovává původní HTTPS schéma.
  • Poskytuje správnou Host hlavičku pro přesměrovací adresy URL a validaci tokenů.

2. Konfigurace cílové skupiny tokenů

Možnost A: Přijmout adresy URL brány i backendu

Přidejte do appsettings.json konfigurace několik platných cílových skupin:

{
  "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"
      ]
    }
  }
}

Alternativně můžete nakonfigurovat více cílových skupin prostřednictvím kódu programu v 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));
    };
});

Možnost B: Přepsání cílové skupiny v zásadách APIM

Nakonfigurujte APIM tak, aby před předáním do back-endu ověřila deklaraci identity cílové skupiny:

<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. Konfigurace koncového bodu pro zdravotní stav

Brány vyžadují neautentizované koncové body stavu pro sondy. Namapujte koncový bod stavu před middlewarem ověřování a obejití ověření tokenu:

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();

Alternativně můžete použít integrovaný framework kontrol stavu ASP.NET Core pro bohatší generování sestav o stavu:

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. Konfigurace CORS za branami

Pokud používáte Azure Front Door nebo APIM s front-endovými aplikacemi, nakonfigurujte CORS tak, aby povolovali požadavky z vašich zdrojů brány:

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();

Důležité

CORS musí být nakonfigurované po předávaných hlavicích a před ověřením.


Integrace se službou Azure API Management

Tato část obsahuje úplnou konfiguraci pro nasazení chráněného rozhraní API za Azure API Management.

Konfigurace back-endového rozhraní API

Nastavení předávaných hlaviček a ověřování Microsoft Entra ID v 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();

Přidejte konfiguraci Microsoft Entra do 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"
  }
}

Přidání příchozích zásad APIM pro ověřování JWT

Definujte příchozí pravidlo, které ověří token JWT, použije omezení rychlosti a předá požadavek backendu.

<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>

Konfigurace nastavení rozhraní APIM API

K dokončení konfigurace APIM použijte následující pojmenované hodnoty a nastavení rozhraní API:

Pojmenované hodnoty (pro opakované použití):

  • tenant-id: ID vašeho tenanta Microsoft Entra
  • backend-api-client-id: Klientské ID backendového API
  • backend-base-url: https://your-backend.azurewebsites.net

Nastavení rozhraní API:

  • Přípona adresy URL rozhraní API: /api (volitelná předpona cesty)
  • Adresa URL webové služby: Je nastavena prostřednictvím zásad s použitím pojmenovaných hodnot
  • Požadováno předplatné: Ano (přidá další vrstvu zabezpečení)

Konfigurace klientské aplikace

Klientské aplikace požadují tokeny pro back-endové rozhraní API, nikoli APIM. Následující kód získá token a zavolá rozhraní API prostřednictvím koncového bodu 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");

Integrace se systémem Azure Front Door

Nakonfigurujte své chráněné rozhraní API pro globální distribuci s využitím služby Azure Front Door.

Konfigurace back-endového rozhraní API

Nastavení přeposlaných hlaviček pro Azure Front Door v 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();

Konfigurace počátečních zdrojů služby Front Door

Na portálu Azure proveďte následující kroky a nastavte zdroj služby Front Door:

  1. Vytvoření profilu služby Front Door
  2. Přidejte skupinu zdrojů s instancemi vaší back-end API
  3. Nakonfigurujte sondy stavu pro /health koncový bod
  4. Nastavte přesměrování pouze na HTTPS
  5. Aktivovat zásadu WAF (volitelně)

Nastavení sondy stavu:

  • Cesta: /health
  • Protokol: HTTPS
  • metody: GET
  • Interval: 30 sekund

Zpracování více oblastí

Když nasadíte do více oblastí prostřednictvím služby Front Door, přidejte regionální povědomí pro protokolování a diagnostiku.

// 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();
});

Ověření tokenů pomocí služby Front Door

Pokud klienti požadují tokeny omezené na adresu URL Front Door, přidejte ji do platného seznamu cílových skupin.

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

Integrace se službou Azure Application Gateway

Nakonfigurujte chráněné rozhraní API za Azure Application Gateway s podporou Web Application Firewall (WAF).

Konfigurace back-endového rozhraní API

Nastavení předávaných hlaviček pro aplikační bránu v 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();

Konfigurace nastavení služby Application Gateway

Na portálu Azure nastavte následující nastavení back-endu, sondy stavu a WAF:

Nastavení back-endu:

  • Protokol: HTTPS (doporučeno) nebo HTTP
  • Port: 443 nebo 80
  • Přepsání backendové cesty: Ne (pokud není potřeba)
  • Vlastní sonda: Ano, ukazuje na /health

Sonda stavu:

  • Protokol: HTTPS nebo HTTP
  • Hostitel: Ponechte výchozí nebo zadejte
  • Cesta: /health
  • Interval: 30 sekund
  • Prahová hodnota není v pořádku: 3

Zásady WAF:

  • Povolení WAF se sadou pravidel OWASP 3.2
  • Důležité: Ujistěte se, že tokeny JWT v Authorization hlavicích nejsou blokované.
  • Možná budete muset vytvořit vyloučení WAF pro RequestHeaderNames, které obsahuje "Authorization".

Nastavení směrování na základě cesty

Pokud používáte pravidla směrování založená na cestě, nakonfigurujte back-endové rozhraní API pro zpracování předpony cesty:

// 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();

Pravidlo služby Application Gateway:

  • Cesta: /api/v1/*
  • Cíl back-endu: Váš back-endový fond
  • Nastavení back-endu: Použití nakonfigurovaných nastavení

Řešení běžných potíží

Tato řešení slouží k řešení nejběžnějších problémů při nasazování chráněných rozhraní API za branami.

Problém: 401 Neautorizováno po nasazení za bránou

Příznaky:

  • Rozhraní API funguje místně, ale vrací 401 za bránou.
  • Token se zdá být platný při dekódování v jwt.ms

Možné příčiny:

  1. Neshoda deklarací cílové skupiny

    # Check token audience
    # Decode token and verify 'aud' claim matches one of:
    # - api://your-client-id
    # - https://your-backend.azurewebsites.net
    # - https://your-gateway-url
    
  2. Chybějící middleware předávaných hlaviček

    // Ensure this is BEFORE authentication
    app.UseForwardedHeaders();
    app.UseAuthentication();
    
  3. Problémy s přesměrováním HTTPS

    // If gateway terminates SSL, may need to disable or configure carefully
    if (!app.Environment.IsDevelopment())
    {
        app.UseHttpsRedirection();
    }
    

Solution:

  • Povolit protokolování ladění pro zobrazení podrobností o ověření tokenu
  • Přidání více platných cílových skupin v ověření tokenu
  • Ověřte, že X-Forwarded-* brána předává hlavičky.

Problém: Selhání sond stavu

Příznaky:

  • Brána označí backend jako nefunkční.
  • Zdravotní koncový bod vrátí hodnotu 401

Solution:

Ujistěte se, že se monitorovací koncový bod spouští před mezičlánkem ověřování.

// 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

Problém: Chyby CORS za službou Azure Front Door

Příznaky:

  • Požadavky typu OPTIONS v předletové fázi selžou
  • Konzola prohlížeče zobrazuje chyby CORS

Solution:

Přidejte Front Door a frontend ke zdrojům zásad 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();

Problém: Upozornění na přeposílané záhlaví v protokolech

Příznaky:

Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware: Unknown proxy

Solution:

Vymažte známé sítě a proxy servery, aby přijímaly předávané hlavičky z infrastruktury 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"));
});

Problém: APIM vrátí hodnotu 401, ale back-end vrátí hodnotu 200

Příznaky:

  • Token je platný pro back-end.
  • Selhání zásad APIM validate-jwt

Solution:

Ověřte, že cílová skupina zásad APIM odpovídá cílové skupině 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>

Problém: Konflikt více schémat ověřování

Příznaky:

  • Použití nosných a jiných schémat JWT
  • Je vybráno nesprávné schéma.

Solution:

Zadejte schéma ověřování explicitně v kontroleru:

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
{
    // ...
}

Dodržujte osvědčené postupy.

Tyto postupy použijte k vytvoření zabezpečeného a odolného nasazení rozhraní API za branami.

1. Hloubková obrana

Vždy ověřte tokeny v back-endovém rozhraní API, i když je brána ověří:

// Gateway validates token (APIM policy)
// Backend ALSO validates token (Microsoft.Identity.Web)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

Konfigurace brány se dá změnit a tokeny se dají přehrát znovu. Hloubková ochrana je důležitá pro zabezpečení.

2. Použití spravovaných identit pro komunikaci typu brána-back-end

Pokud brána volá back-end s vlastní identitou, nakonfigurujte back-end tak, aby přijímal tokeny uživatele i tokeny spravované identity:

// 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. Monitorování metrik brány

Sledujte tyto klíčové metriky, abyste zachovali přehled o nasazení brány:

  • Chybová míra 401/403
  • Selhání ověřování tokenů
  • Selhání diagnostické sondy
  • Přeposílané hlavičky (pro účely ladění)

4. Použití Application Insights

Přidání telemetrie Application Insights do vlastností požadavků specifických pro bránu:

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. Oddělení zdravotního stavu od stavu připravenosti

Pro rozlišení kontrol živosti (je služba spuštěná?) a připravenosti (může služba přijímat provoz?) použijte odlišné koncové body:

// 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. Zdokumentujte konfiguraci brány.

Vytvořte stránku README nebo wikiwebu, která dokumentuje:

  • Které brány se používají
  • Očekávání cílové skupiny tokenů
  • Konfigurace CORS
  • Koncové body sondy stavu
  • Konfigurace předávaných hlaviček
  • Postupy pro nouzové vrácení zpět

Vytvoření kompletního příkladu s Azure API Management

Tato část nabízí kompletní, pro produkční prostředí připravený příklad API ASP.NET Core za Azure API Management s ověřováním pomocí Microsoft Entra ID.

Back-endové rozhraní API (ASP.NET Core)

Následující Program.cs konfiguruje předávané hlavičky, ověřování Microsoft Entra, kontroly stavu a 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();

Do appsettings.json přidejte následující konfiguraci Microsoft Entra a Application Insights:

{
  "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"
  }
}

Následující kontroler vyžaduje ověření a zaznamenává předávané hlavičky pro účely ladění.

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

Konfigurace APIM

Následující příchozí zásada ověřuje tokeny JWT, aplikuje omezení rychlosti, předává hlavičky a konfiguruje 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>