Initial import into Gitea
This commit is contained in:
@@ -248,11 +248,26 @@ public sealed class MultiProviderAuthMiddleware
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard Entra ID
|
||||
// Standard Entra ID — could be CIAM tenant or Staff tenant (Tech, Admin)
|
||||
// Detect by comparing issuer against configured Staff tenant ID
|
||||
var staffTenantId = _config["Auth:Microsoft:StaffTenantId"];
|
||||
var staffClientId = _config["Auth:Microsoft:StaffClientId"];
|
||||
|
||||
var isStaff = !string.IsNullOrWhiteSpace(staffTenantId) &&
|
||||
jwt.Issuer.Contains(staffTenantId, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (isStaff)
|
||||
{
|
||||
tenantId = staffTenantId!;
|
||||
clientId = staffClientId ?? clientId;
|
||||
_logger.LogWarning("[Auth] Staff Entra token detected | tenant={Tenant} | Corr={Corr}", tenantId, corrId);
|
||||
clientContext.IsStaff = true;
|
||||
}
|
||||
|
||||
authority = $"https://login.microsoftonline.com/{tenantId}/v2.0";
|
||||
metadataAddress = $"{authority}/.well-known/openid-configuration";
|
||||
validIssuers = new[]
|
||||
{
|
||||
validIssuers = new[]
|
||||
{
|
||||
$"https://login.microsoftonline.com/{tenantId}/v2.0",
|
||||
$"https://sts.windows.net/{tenantId}/"
|
||||
};
|
||||
@@ -342,9 +357,17 @@ public sealed class MultiProviderAuthMiddleware
|
||||
/// </summary>
|
||||
private static void ExtractClaims(ClaimsPrincipal principal, ClientContext clientContext)
|
||||
{
|
||||
// Always extract oid explicitly — used for activity logging and identity.
|
||||
// For standard Entra access tokens oid may be under the full claim URI.
|
||||
var oid = principal.FindFirstValue("oid")
|
||||
?? principal.FindFirstValue("http://schemas.microsoft.com/identity/claims/objectidentifier");
|
||||
|
||||
clientContext.EntraOid = oid;
|
||||
|
||||
// ClientId: prefer oid, fall back to sub
|
||||
clientContext.ClientId =
|
||||
principal.FindFirstValue("oid") ?? // Microsoft object ID
|
||||
principal.FindFirstValue("sub") ?? // Standard subject
|
||||
oid ??
|
||||
principal.FindFirstValue("sub") ??
|
||||
principal.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
|
||||
clientContext.Email =
|
||||
@@ -389,7 +412,9 @@ public sealed class MultiProviderAuthMiddleware
|
||||
try
|
||||
{
|
||||
var rqst = JsonSerializer.Serialize(new { sessionToken = token });
|
||||
var resp = await sql.ExecProcAsync("dbo.spSession", "validate", rqst, ct: context.RequestAborted);
|
||||
|
||||
var sessionProc = "dbo.spClientSession"; // Gateway handles CIAM client sessions only
|
||||
var resp = await sql.ExecProcAsync(sessionProc, "validate", rqst, ct: context.RequestAborted);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(resp))
|
||||
{
|
||||
@@ -412,8 +437,22 @@ public sealed class MultiProviderAuthMiddleware
|
||||
clientContext.Role = data.TryGetProperty("role", out var role) ? role.GetString() : null;
|
||||
clientContext.IsDevBypass = false;
|
||||
|
||||
_logger.LogWarning("[Auth] Session validated OK | ClientId={ClientId} Email={Email} | Corr={Corr}",
|
||||
clientContext.ClientId, clientContext.Email, corrId);
|
||||
// TenantId: session data first, then X-Tenant-Id header fallback
|
||||
// (In agency model, this is the client's Google Ads customer ID)
|
||||
clientContext.TenantId =
|
||||
data.TryGetProperty("tenantId", out var tenId) ? tenId.GetString() :
|
||||
data.TryGetProperty("googleCustomerId", out var gcid) ? gcid.GetString() :
|
||||
null;
|
||||
|
||||
// Fall back to X-Tenant-Id header if not in session data
|
||||
if (string.IsNullOrWhiteSpace(clientContext.TenantId) &&
|
||||
context.Request.Headers.TryGetValue("X-Tenant-Id", out var tenantHeader))
|
||||
{
|
||||
clientContext.TenantId = tenantHeader.FirstOrDefault();
|
||||
}
|
||||
|
||||
_logger.LogWarning("[Auth] Session validated OK | ClientId={ClientId} Email={Email} IsAdmin={IsAdmin} | Corr={Corr}",
|
||||
clientContext.ClientId, clientContext.Email, clientContext.IsAdmin, corrId);
|
||||
|
||||
return clientContext.IsAuthenticated;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user