Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa guida illustra come distribuire ASP.NET Core API Web protette con Microsoft. Identity.Web dietro Azure gateway API e proxy inversi, tra cui Gestione API di Azure (GESTIONE API), Frontdoor di Azure e gateway applicazione di Azure.
Informazioni generali
Quando si distribuiscono API protette dietro i gateway, è necessario gestire:
- Intestazioni inoltrate - Mantenere il contesto di richiesta originale (schema, host, IP)
- Convalida dei token : assicurarsi che le attestazioni del gruppo di destinatari corrispondano agli URL del gateway
- Configurazione CORS : gestire correttamente le richieste tra le origini
- Endpoint di integrità : fornire controlli di integrità non autenticati
- Routing basato sul percorso - Supportare i prefissi di percorso a livello di gateway
- Terminazione SSL/TLS : gestire correttamente HTTPS quando il gateway termina SSL
Scenari di gateway comuni
Gestione API di Azure (APIM)
Caso d'uso: Gateway API aziendale con criteri, limitazione della frequenza, trasformazione
Architettura:
Client → Microsoft Entra ID → Token
Client → APIM (apim.azure-api.net) → Backend API (app.azurewebsites.net)
Considerazioni chiave:
- Alcuni criteri di Gestione API possono convalidare i token JWT prima dell'inoltro al back-end
- L'API back-end convalida ancora i token
- L'attestazione del gruppo di destinatari deve corrispondere all'URL di Gestione API o all'URL back-end (configurare di conseguenza)
Frontdoor di Azure
Caso d'uso: Bilanciamento del carico globale, rete CDN, protezione DDoS
Architettura:
Client → Microsoft Entra ID → Token
Client → Front Door (azurefd.net) → Backend API (regional endpoints)
Considerazioni chiave:
- Frontdoor inoltra le richieste con
X-Forwarded-*intestazioni - Terminazione SSL/TLS in Frontdoor
- La convalida del gruppo di destinatari dei token richiede la configurazione
gateway applicazione di Azure
Caso d'uso: Bilanciamento del carico a livello di area, WAF, routing basato sul percorso
Architettura:
Client → Microsoft Entra ID → Token
Client → Application Gateway → Backend API (multiple instances)
Considerazioni chiave:
- Integrazione di Web application firewall (WAF)
- Regole di routing basate sul percorso
- I probe di integrità back-end necessitano di endpoint non autenticati
Modelli di configurazione
1. Middleware delle intestazioni inoltrate
Configurare sempre il middleware delle intestazioni inoltrate quando si è dietro un gateway:
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();
Perché questo è importante:
- Mantiene l'indirizzo IP del client originale per la registrazione
- Assicura che
HttpContext.Request.Schemerifletta https originale - Intestazione corretta
Hostper gli URL di reindirizzamento e la convalida del token
2. Configurazione del gruppo di destinatari dei token
Opzione A: accettare url gateway e back-end
{
"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"
]
}
}
}
Configurazione del codice:
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));
};
});
Opzione B: Riscrivere i destinatari nei criteri di Gestione API
Configurare Gestione API per riscrivere l'attestazione del gruppo di destinatari prima dell'inoltro:
<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. Configurazione dell'endpoint di integrità
I gateway necessitano di endpoint di integrità non autenticati per i probe:
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();
Alternative con controlli di integrità ASP.NET Core:
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. Configurazione CORS dietro i gateway
Quando si usano Frontdoor di Azure o Gestione API con applicazioni front-end:
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: È necessario configurare CORS dopo le intestazioni inoltrate e prima dell'autenticazione.
Integrazione di Gestione API di Azure (APIM)
Completare la configurazione di Gestione API
1. Configurazione dell'API back-end
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();
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"
}
}
2. Criteri in ingresso di Gestione API (convalida JWT)
<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>
3. Configurazione api di Gestione API
Valori denominati (per la riutilizzabilità):
-
tenant-id: ID tenant Microsoft Entra -
backend-api-client-id: ID client dell'API back-end -
backend-base-url:https://your-backend.azurewebsites.net
Impostazioni API:
-
Suffisso URL API:
/api(prefisso del percorso facoltativo) - URL del servizio Web: impostare tramite criteri usando valori denominati
- Sottoscrizione obbligatoria: Sì (aggiunge un altro livello di sicurezza)
4. Configurazione dell'applicazione client
Le app client richiedono token per l'API back-end, non gestione API:
// 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");
integrazione di Frontdoor di Azure
Configurazione per la distribuzione globale
1. Configurazione dell'API back-end
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();
2. Configurazione dell'origine frontdoor
portale di Azure Impostazioni:
- Creare un profilo frontdoor
- Aggiungere un gruppo di origine con le istanze dell'API back-end
- Configurare i probe di integrità per
/healthl'endpoint - Impostare solo l'inoltro HTTPS
- Abilitare i criteri WAF (facoltativo)
Impostazioni probe di integrità:
-
Percorso:
/health - Protocollo: HTTPS
- Metodo: GET
- Intervallo: 30 secondi
3. Gestione di più aree
Quando si esegue la distribuzione in più aree dietro Frontdoor:
// 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();
});
4. Frontdoor e convalida dei token
I destinatari dei token devono includere l'URL di Frontdoor se i client richiedono token:
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"]
};
});
integrazione di gateway applicazione di Azure
Configurazione con WAF
1. Configurazione dell'API back-end
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();
2. Configurazione del gateway applicazione
Impostazioni back-end:
- Protocollo: HTTPS (scelta consigliata) o HTTP
- Porta: 443 o 80
- Eseguire l'override del percorso back-end: No (a meno che non sia necessario)
-
Probe personalizzato: Sì, che punta a
/health
Probe di integrità:
- Protocollo: HTTPS o HTTP
- Host: lasciare l'impostazione predefinita o specificare
-
Percorso:
/health - Intervallo: 30 secondi
- Soglia non integra: 3
Criteri WAF:
- Abilitare WAF con il set di regole OWASP 3.2
- Importante: assicurarsi che i token JWT nelle intestazioni di autorizzazione non siano bloccati
- Potrebbe essere necessario creare esclusioni WAF per
RequestHeaderNamescontenere "Autorizzazione"
3. Routing basato sul percorso
Quando si usano regole di routing basate sul percorso:
// 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();
Regola del gateway applicazione:
-
Percorso:
/api/v1/* - Destinazione back-end: pool back-end
- Impostazioni back-end: usare le impostazioni configurate
Risoluzione dei problemi
Problema: 401 Non autorizzato dopo la distribuzione dietro il gateway
Sintomi:
- L'API funziona in locale ma restituisce 401 dietro il gateway
- Il token sembra valido quando decodificato in jwt.ms
Possibili cause:
Mancata corrispondenza dell'attestazione del gruppo di destinatari
# 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 delle intestazioni inoltrate mancanti
// Ensure this is BEFORE authentication app.UseForwardedHeaders(); app.UseAuthentication();Problemi di reindirizzamento HTTPS
// If gateway terminates SSL, may need to disable or configure carefully if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); }
Soluzione:
- Abilitare la registrazione di debug per visualizzare i dettagli di convalida dei token
- Aggiungere più gruppi di destinatari validi nella convalida del token
- Controllare che le intestazioni X-Forwarded-* vengano inoltrate dal gateway
Problema: i probe di integrità hanno esito negativo
Sintomi:
- Il gateway contrassegna il back-end come non integro
- L'endpoint di integrità restituisce 401
Soluzione:
// 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: errori CORS dietro Frontdoor
Sintomi:
- Le richieste OPTIONS preliminari hanno esito negativo
- La console del browser mostra gli errori CORS
Soluzione:
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: i log di convalida dei token mostrano avvisi "Intestazione inoltrata"
Sintomi:
Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware: Unknown proxy
Soluzione:
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: Gestione API restituisce 401 ma il back-end restituisce 200
Sintomi:
- Il token è valido per il back-end
- I criteri validate-jwt di Gestione API hanno esito negativo
Soluzione:
Controllare che il gruppo di destinatari dei criteri di Gestione API corrisponda al gruppo di destinatari dei 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: conflitti tra più schemi di autenticazione
Sintomi:
- Uso sia del bearer JWT che di altri schemi
- Schema errato selezionato
Soluzione:
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
{
// ...
}
Procedure consigliate
1. Difesa in profondità
Convalidare sempre i token nell'API back-end, anche se il gateway li convalida
// Gateway validates token (APIM policy)
// Backend ALSO validates token (Microsoft.Identity.Web)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
Perché: La configurazione del gateway può cambiare, i token possono essere riprodotti, la difesa avanzata è fondamentale per la sicurezza.
2. Usare le identità gestite per gateway-to-backend
Se il gateway deve chiamare il back-end con la propria identità:
// 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. Monitorare le metriche del gateway
- Tenere traccia delle percentuali di errore 401/403
- Monitorare gli errori di convalida dei token
- Avviso per gli errori del probe di integrità
- Registrare le intestazioni inoltrate per il debug
4. Usare Application Insights
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. Separare l'integrità da pronto
// 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. Documentare la configurazione del gateway
Creare una pagina README o wiki che documenta:
- Quali gateway sono in uso
- Aspettative dei destinatari dei token
- Configurazione CORS
- Endpoint del probe di integrità
- Configurazione delle intestazioni inoltrate
- Procedure di rollback di emergenza
Esempio completo: API dietro Gestione API di Azure
API back-end (ASP.NET Core)
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"))
.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();
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"
}
}
WeatherForecastController.cs:
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" });
}
}
Configurazione di Gestione API
Criteri in ingresso:
<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>