Stabilzie modules
This commit is contained in:
@@ -67,11 +67,18 @@ public sealed class IdentityHeaderPolicyMiddleware
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 0: Preserve client-sent tenant header before stripping.
|
||||
// When the Gateway runs in AllowAnonymous mode (no JWT validation),
|
||||
// the principal has no claims and we cannot determine tenant from the token.
|
||||
// In that case, we pass through the client-provided value and let the
|
||||
// upstream service validate it against the JWT's tenant claim.
|
||||
var clientTenant = context.Request.Headers["X-StellaOps-Tenant"].ToString();
|
||||
|
||||
// Step 1: Strip all reserved identity headers from incoming request
|
||||
StripReservedHeaders(context);
|
||||
|
||||
// Step 2: Extract identity from validated principal
|
||||
var identity = ExtractIdentity(context);
|
||||
var identity = ExtractIdentity(context, clientTenant);
|
||||
|
||||
// Step 3: Store normalized identity in HttpContext.Items
|
||||
StoreIdentityContext(context, identity);
|
||||
@@ -97,17 +104,23 @@ public sealed class IdentityHeaderPolicyMiddleware
|
||||
}
|
||||
}
|
||||
|
||||
private IdentityContext ExtractIdentity(HttpContext context)
|
||||
private IdentityContext ExtractIdentity(HttpContext context, string? clientTenant = null)
|
||||
{
|
||||
var principal = context.User;
|
||||
var isAuthenticated = principal.Identity?.IsAuthenticated == true;
|
||||
|
||||
if (!isAuthenticated)
|
||||
{
|
||||
// In AllowAnonymous mode the Gateway cannot validate identity claims.
|
||||
// Pass through the client-provided tenant so the upstream service
|
||||
// can validate it against the JWT's own tenant claim.
|
||||
var passThruTenant = !string.IsNullOrWhiteSpace(clientTenant) ? clientTenant.Trim() : null;
|
||||
|
||||
return new IdentityContext
|
||||
{
|
||||
IsAnonymous = true,
|
||||
Actor = "anonymous",
|
||||
Tenant = passThruTenant,
|
||||
Scopes = _options.AnonymousScopes ?? []
|
||||
};
|
||||
}
|
||||
@@ -115,9 +128,12 @@ public sealed class IdentityHeaderPolicyMiddleware
|
||||
// Extract subject (actor)
|
||||
var actor = principal.FindFirstValue(StellaOpsClaimTypes.Subject);
|
||||
|
||||
// Extract tenant - try canonical claim first, then legacy 'tid'
|
||||
// Extract tenant - try canonical claim first, then legacy 'tid',
|
||||
// then client-provided header, then fall back to "default"
|
||||
var tenant = principal.FindFirstValue(StellaOpsClaimTypes.Tenant)
|
||||
?? principal.FindFirstValue("tid");
|
||||
?? principal.FindFirstValue("tid")
|
||||
?? (!string.IsNullOrWhiteSpace(clientTenant) ? clientTenant.Trim() : null)
|
||||
?? "default";
|
||||
|
||||
// Extract project (optional)
|
||||
var project = principal.FindFirstValue(StellaOpsClaimTypes.Project);
|
||||
|
||||
Reference in New Issue
Block a user