save progress
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Auth.Abstractions;
|
||||
|
||||
namespace StellaOps.AirGap.Controller.Auth;
|
||||
|
||||
@@ -21,12 +23,28 @@ public sealed class HeaderScopeAuthenticationHandler : AuthenticationHandler<Aut
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
// Accept any request; scopes are read from `scope` header (space-separated)
|
||||
var claims = new List<Claim> { new(ClaimTypes.NameIdentifier, "anonymous") };
|
||||
|
||||
if (Request.Headers.TryGetValue("scope", out var scopeHeader))
|
||||
var scopes = ExtractScopes(Request.Headers);
|
||||
if (scopes.Count == 0)
|
||||
{
|
||||
claims.Add(new("scope", scopeHeader.ToString()));
|
||||
return Task.FromResult(AuthenticateResult.Fail("scope_header_missing"));
|
||||
}
|
||||
|
||||
var claims = new List<Claim>
|
||||
{
|
||||
new(ClaimTypes.NameIdentifier, "header-scope"),
|
||||
new(StellaOpsClaimTypes.Subject, "header-scope"),
|
||||
new(StellaOpsClaimTypes.Scope, string.Join(' ', scopes))
|
||||
};
|
||||
|
||||
foreach (var scope in scopes)
|
||||
{
|
||||
claims.Add(new Claim(StellaOpsClaimTypes.ScopeItem, scope));
|
||||
}
|
||||
|
||||
if (TryGetTenantHeader(Request.Headers, out var tenantId))
|
||||
{
|
||||
claims.Add(new Claim(StellaOpsClaimTypes.Tenant, tenantId));
|
||||
claims.Add(new Claim("tid", tenantId));
|
||||
}
|
||||
|
||||
var identity = new ClaimsIdentity(claims, SchemeName);
|
||||
@@ -34,4 +52,49 @@ public sealed class HeaderScopeAuthenticationHandler : AuthenticationHandler<Aut
|
||||
var ticket = new AuthenticationTicket(principal, SchemeName);
|
||||
return Task.FromResult(AuthenticateResult.Success(ticket));
|
||||
}
|
||||
|
||||
private static HashSet<string> ExtractScopes(IHeaderDictionary headers)
|
||||
{
|
||||
var scopes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
AddScopes(headers, "scope", scopes);
|
||||
AddScopes(headers, "scp", scopes);
|
||||
|
||||
return scopes;
|
||||
}
|
||||
|
||||
private static void AddScopes(IHeaderDictionary headers, string headerName, ISet<string> scopes)
|
||||
{
|
||||
if (!headers.TryGetValue(headerName, out var values))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
foreach (var scope in value.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
||||
{
|
||||
scopes.Add(scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryGetTenantHeader(IHeaderDictionary headers, out string tenantId)
|
||||
{
|
||||
tenantId = string.Empty;
|
||||
|
||||
if (headers.TryGetValue("x-tenant-id", out var headerValue) && !string.IsNullOrWhiteSpace(headerValue))
|
||||
{
|
||||
tenantId = headerValue.ToString().Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (headers.TryGetValue("tid", out var legacyValue) && !string.IsNullOrWhiteSpace(legacyValue))
|
||||
{
|
||||
tenantId = legacyValue.ToString().Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user