Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Stellen Sie ASP.NET Core Web-APIs bereit, die durch Microsoft.Identity.Web geschützt sind, hinter Azure API-Gateways und Reverse-Proxys, einschließlich Azure API Management (APIM), Azure Front Door und Azure Application Gateway.
Grundlegendes zu Gatewayanforderungen
Wenn Sie geschützte APIs hinter Gateways bereitstellen, müssen Sie mehrere Probleme behandeln:
- Weitergeleitete Header – Ursprüngliche Anforderungskontext beibehalten (Schema, Host, IP)
- Tokenüberprüfung – Sicherstellen, dass Gateway-URLs für Zielgruppenansprüche übereinstimmen
- CORS-Konfiguration – Behandeln von ursprungsübergreifenden Anforderungen ordnungsgemäß
- Gesundheitsendpunkte – Bereitstellung von Prüfungen ohne Authentifizierung
- Pfadbasiertes Routing – Unterstützen von Pfadpräfixen auf Gatewayebene
- SSL/TLS-Beendigung – Behandeln von HTTPS ordnungsgemäß, wenn das Gateway SSL beendet
Überprüfen allgemeiner Gatewayszenarien
Wählen Sie ein Gateway basierend auf Ihren Anforderungen aus. In den folgenden Abschnitten werden die am häufigsten verwendeten Azure Gatewaydienste für geschützte APIs beschrieben.
Azure API Management (APIM)
Anwendungsfall: Enterprise-API-Gateway mit Richtlinien, Ratelimitierung, Transformation
Architektur:
Client → Microsoft Entra ID → Token
Client → APIM (apim.azure-api.net) → Backend API (app.azurewebsites.net)
Wichtige Überlegungen:
- APIM-Richtlinien können JWT-Token überprüfen, bevor sie an das Back-End weitergeleitet werden.
- Die Back-End-API überprüft weiterhin Token
- Der Zielgruppenanspruch muss mit der APIM-URL oder Back-End-URL übereinstimmen (entsprechend konfigurieren)
Azure Front Door
Anwendungsfall: Globaler Lastenausgleich, CDN- und DDoS-Schutz
Architektur:
Client → Microsoft Entra ID → Token
Client → Front Door (azurefd.net) → Backend API (regional endpoints)
Wichtige Überlegungen:
- Front Door leitet Anforderungen mit
X-Forwarded-*Headern weiter. - SSL/TLS-Beendigung bei Front Door
- Konfiguration für die Zielgruppenvalidierung von Tokens erforderlich
Azure Application Gateway
Anwendungsfall: Regionales Lastenausgleich, WAF, pfadbasiertes Routing
Architektur:
Client → Microsoft Entra ID → Token
Client → Application Gateway → Backend API (multiple instances)
Wichtige Überlegungen:
- Web Application Firewall(WAF)-Integration
- Pfadbasierte Routingregeln
- Backend-Gesundheitsprüfungen benötigen nicht authentifizierte Endpunkte
Konfigurieren allgemeiner Muster
Wenden Sie diese Konfigurationsmuster an, um sicherzustellen, dass Ihre geschützte API hinter jedem Gateway ordnungsgemäß funktioniert.
Middleware für weitergeleitete Header
Konfigurieren Sie die Middleware für weitergeleitete Headers immer, wenn sie sich hinter einem Gateway befindet. Der folgende Code registriert die Middleware und legt sie so fest, dass sie vor der Authentifizierung ausgeführt wird:
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();
Die Middleware für weitergeleitete Header ist kritisch, da sie:
- Behält die ursprüngliche Client-IP-Adresse für die Protokollierung bei
- Stellt sicher, dass
HttpContext.Request.Schemedas ursprüngliche HTTPS-Schema wiedergibt. - Stellt den richtigen
HostHeader für Umleitungs-URLs und Tokenüberprüfung bereit.
2. Tokenzielgruppen-Konfiguration
Option A: Akzeptieren von Gateway- und Back-End-URLs
Fügen Sie Ihrer appsettings.json-Konfiguration mehrere gültige Zielgruppen hinzu.
{
"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"
]
}
}
}
Alternativ lässt sich die Konfiguration mehrerer Zielgruppen programmgesteuert in 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));
};
});
Option B: Umschreiben der Zielgruppe in der APIM-Richtlinie
Konfigurieren Sie APIM, um den Zielgruppenanspruch vor der Weiterleitung an das Back-End zu überprüfen:
<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. Konfiguration des Statusprüfungsendpunkts
Gateways erfordern unauthentifizierte Integritätsendpunkte für Überprüfungen. Legen Sie einen Gesundheitsendpunkt vor der Authentifizierungs-Middleware an, um die Tokenüberprüfung zu umgehen.
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();
Alternativ können Sie das integrierte ASP.NET Core-Framework für Integritätsprüfungen verwenden, um umfassendere Integritätsberichte zu erhalten:
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. CORS-Konfiguration hinter Gateways
Wenn Sie Azure Front Door oder APIM mit Frontend-Anwendungen verwenden, konfigurieren Sie CORS so, dass Anforderungen von Ihren Gateway-Ursprüngen zugelassen werden:
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();
Wichtig
CORS muss nach weitergeleiteten Headern und vor der Authentifizierung konfiguriert werden.
Integrieren mit Azure API Management
Dieser Abschnitt enthält die vollständige Konfiguration für die Bereitstellung einer geschützten API hinter Azure API Management.
Konfigurieren der Back-End-API
Richten Sie weitergeleitete Header und Microsoft Entra ID Authentifizierung in Program.cs ein:
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();
Fügen Sie die Microsoft Entra-Konfiguration zu appsettings.json hinzu:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-backend-api-client-id",
"Audience": "api://your-backend-api-client-id"
}
}
Hinzufügen einer eingehenden API-Management-Richtlinie zur JWT-Validierung
Definieren Sie eine eingehende Richtlinie, die das JWT-Token überprüft, die Ratelimitierung anwendet und die Anforderung an das Back-End weiterleitet:
<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>
Konfigurieren von APIM-API-Einstellungen
Verwenden Sie die folgenden benannten Werte und API-Einstellungen, um die APIM-Konfiguration abzuschließen:
Benannte Werte (zur Wiederverwertbarkeit):
-
tenant-id: Ihre Microsoft Entra Mandanten-ID -
backend-api-client-id: Client-ID der Back-End-API -
backend-base-url:https://your-backend.azurewebsites.net
API-Einstellungen:
-
API-URL-Suffix:
/api(optionales Pfadpräfix) - Webdienst-URL: Über eine Richtlinie mit benannten Werten festgelegt
- Abonnement erforderlich: Ja (fügt eine weitere Sicherheitsebene hinzu)
Konfigurieren der Clientanwendung
Client-Apps fordern Token für die Back-End-API an, nicht APIM. Der folgende Code ruft ein Token ab und ruft die API über den APIM-Endpunkt auf:
// 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");
Integration mit Azure Front Door
Konfigurieren Sie Ihre geschützte API für die globale Verteilung hinter Azure Front Door.
Konfigurieren der Back-End-API
Richten Sie weitergeleitete Kopfzeilen für Azure Front Door in Program.cs ein:
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();
Konfigurieren der Ursprünge der Fronttür
Führen Sie die folgenden Schritte im Azure Portal aus, um den Front Door-Ursprung einzurichten:
- Erstellen eines Front Door-Profils
- Ursprungsgruppe mit Ihren Backend-API-Instanzen hinzufügen
- Konfigurieren Sie Integritätssonden für
/healthEndpunkt - Nur HTTPS-Weiterleitung festlegen
- Aktivieren der WAF-Richtlinie (optional)
Gesundheitssondeneinstellungen:
-
Pfad:
/health - Protokoll: HTTPS
- Methode: GET
- Intervall: 30 Sekunden
Verwalten mehrerer Regionen
Wenn Sie über Front Door in mehreren Regionen bereitstellen, fügen Sie Regionsbewusstsein für Protokollierung und Diagnose hinzu.
// 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();
});
Validierung von Token mit Front Door
Wenn Clients Token anfordern, die auf die Front Door-URL festgelegt sind, fügen Sie sie der Liste der gültigen Zielgruppen hinzu:
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"]
};
});
Integrieren mit Azure-Anwendungsgateway
Konfigurieren Sie Ihre geschützte API hinter Azure Application Gateway mit Web Application Firewall(WAF)-Unterstützung.
Konfigurieren der Back-End-API
Richten Sie weitergeleitete Header für das Anwendungsgateway in Program.cs ein:
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();
Konfigurieren von Anwendungsgatewayeinstellungen
Legen Sie die folgenden Backend-, Verfügbarkeitsüberprüfungs- und WAF-Einstellungen im Azure-Portal fest:
Back-End-Einstellungen:
- Protokoll: HTTPS (empfohlen) oder HTTP
- Port: 443 oder 80
- Back-End-Pfad außer Kraft setzen: Nein (es sei denn, erforderlich)
-
Benutzerdefinierter Prüfpunkt: Ja, zeigt auf
/health
Health-Check-Sonde:
- Protokoll: HTTPS oder HTTP
- Host: Standardwert belassen oder angeben
-
Pfad:
/health - Intervall: 30 Sekunden
- Schwellenwert für ungesund: 3
WAF-Richtlinie:
- Aktivieren von WAF mit OWASP 3.2-Regelsatz
-
Wichtig: Sicherstellen, dass JWT-Token in
AuthorizationHeadern nicht blockiert werden - Möglicherweise müssen Sie WAF-Ausschlüsse für
RequestHeaderNameserstellen, die "Autorisierung" enthalten.
Einrichten des pfadbasierten Routings
Wenn Sie pfadbasierte Routingregeln verwenden, konfigurieren Sie Ihre Back-End-API für die Behandlung des Pfadpräfixes:
// 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();
Regel des Anwendungsgateways:
-
Pfad:
/api/v1/* - Back-End-Ziel: Ihr Back-End-Pool
- Back-End-Einstellungen: Verwenden von konfigurierten Einstellungen
Häufige Probleme beheben
Verwenden Sie diese Lösungen, um die häufigsten Probleme bei der Bereitstellung geschützter APIs hinter Gateways zu beheben.
Problem: 401 Nicht autorisiert nach der Bereitstellung hinter dem Gateway
Symptome:
- API funktioniert lokal, gibt aber hinter dem Gateway 401 zurück.
- Token scheint gültig, wenn es bei jwt.ms decodiert wird
Mögliche Ursachen:
Nichtübereinstimmung bei Zielgruppenansprüchen
# Check token audience # Decode token and verify 'aud' claim matches one of: # - api://your-client-id # - https://your-backend.azurewebsites.net # - https://your-gateway-urlFehlende Middleware für weitergeleitete Header
// Ensure this is BEFORE authentication app.UseForwardedHeaders(); app.UseAuthentication();PROBLEME bei der HTTPS-Umleitung
// If gateway terminates SSL, may need to disable or configure carefully if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Lösung:
- Aktivieren der Debugprotokollierung zum Anzeigen von Tokenüberprüfungsdetails
- Hinzufügen mehrerer gültiger Zielgruppen in der Tokenüberprüfung
- Überprüfen, ob
X-Forwarded-*Header vom Gateway weitergeleitet werden
Problem: Gesundheitsüberprüfungen fehlgeschlagen
Symptome:
- Gateway kennzeichnet das Back-End als fehlerhaft
- Der Gesundheitsendpunkt gibt 401 zurück.
Lösung:
Stellen Sie sicher, dass der Integritätsendpunkt vor der Authentifizierungs-Middleware ausgeführt wird:
// 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
Problem: CORS-Fehler hinter Front Door
Symptome:
- Fehler bei Preflight OPTIONS-Anforderungen
- Browserkonsole zeigt CORS-Fehler an
Lösung:
Fügen Sie Ihre Front Door- und Frontend-Ursprünge zur CORS-Richtlinie hinzu:
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();
Problem: Warnungen zu "Weitergeleitete Header" in Protokollen
Symptome:
Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware: Unknown proxy
Lösung:
Löschen Sie die bekannten Netzwerke und Proxys, um weitergeleitete Header aus Azure Infrastruktur zu akzeptieren:
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"));
});
Problem: APIM gibt 401 zurück, aber Back-End gibt 200 zurück.
Symptome:
- Das Token ist für das Back-End gültig.
- APIM-Richtlinie
validate-jwtschlägt fehl
Lösung:
Überprüfen Sie, ob die Zielgruppe der APIM-Richtlinie mit der Zielgruppe des Tokens übereinstimmt.
<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>
Problem: Konflikte mit mehreren Authentifizierungsschemas
Symptome:
- Verwendung von JWT-Bearer und anderen Schemata
- Falsches Schema ist ausgewählt
Lösung:
Geben Sie das Authentifizierungsschema explizit im Controller an:
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
{
// ...
}
Bewährte Methoden befolgen
Wenden Sie diese Methoden an, um eine sichere, robuste API-Bereitstellung hinter Gateways zu erstellen.
1. Verteidigung im Detail
Überprüfen Sie Token immer in der Back-End-API, auch wenn das Gateway sie überprüft:
// Gateway validates token (APIM policy)
// Backend ALSO validates token (Microsoft.Identity.Web)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
Die Gatewaykonfiguration kann geändert werden, und Token können wiedergegeben werden. Die Tiefenverteidigung ist für die Sicherheit von entscheidender Bedeutung.
2. Verwenden von verwalteten Identitäten für die Gateway-zu-Back-End-Kommunikation
Wenn Ihr Gateway das Back-End mit eigener Identität aufruft, konfigurieren Sie das Back-End so, dass sowohl Benutzertoken als auch verwaltete Identitätstoken akzeptiert werden:
// 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. Überwachen von Gatewaymetriken
Verfolgen Sie diese wichtigen Metriken, um die Sichtbarkeit Ihrer Gatewaybereitstellung aufrechtzuerhalten:
- Fehlerraten von 401/403
- Tokenüberprüfungsfehler
- Gesundheitsprüfungsfehler
- Weitergeleitete Kopfzeilen (zum Debuggen)
4. Verwenden von Application Insights
Fügen Sie die Telemetrie von Application Insights hinzu, um gatewayspezifische Anforderungseigenschaften zu protokollieren:
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. Trennen Sie Gesundheit und Bereitschaft
Verwenden Sie verschiedene Endpunkte für die Lebendigkeitsprüfungen (läuft der Dienst?) und die Bereitschaftsprüfungen (kann der Dienst Datenverkehr akzeptieren?)
// 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. Dokumentieren der Gateway-Konfiguration
Erstellen Sie eine README- oder Wiki-Seite, die Dokumente enthält:
- Welche Gateways verwendet werden
- Erwartungen der Token-Zielgruppe
- CORS-Konfiguration
- Endpunkte für Integritätssonden
- Konfiguration von weitergeleiteten Headern
- Notfall-Rollback-Prozeduren
Erstellen eines vollständigen Beispiels mit Azure API Management
Dieser Abschnitt enthält ein vollständiges, produktionsbereites Beispiel für eine ASP.NET Core-API hinter Azure API Management mit Microsoft Entra ID Authentifizierung.
Back-End-API (ASP.NET Core)
Im folgenden Program.cs werden weitergeleitete Header, die Microsoft Entra-Authentifizierung, Integritätsprüfungen und Application Insights konfiguriert:
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();
Fügen Sie die folgende Microsoft Entra- und Application Insights-Konfiguration zu appsettings.json hinzu:
{
"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"
}
}
Der folgende Controller erfordert eine Authentifizierung und protokolliert weitergeleitete Header zur Fehlerbehebung.
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" });
}
}
APIM-Konfiguration
Die folgende eingehende Richtlinie überprüft JWT-Token, wendet Ratenbegrenzung an, leitet Header weiter und konfiguriert 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>