save changes
This commit is contained in:
@@ -4,7 +4,7 @@ namespace StellaOps.Scheduler.WebService.Auth;
|
||||
|
||||
internal sealed class HeaderScopeAuthorizer : IScopeAuthorizer
|
||||
{
|
||||
private const string ScopeHeader = "X-Scopes";
|
||||
private const string ScopeHeader = "X-StellaOps-Scopes";
|
||||
|
||||
public void EnsureScope(HttpContext context, string requiredScope)
|
||||
{
|
||||
@@ -23,9 +23,30 @@ internal sealed class HeaderScopeAuthorizer : IScopeAuthorizer
|
||||
.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (!scopes.Contains(requiredScope))
|
||||
if (scopes.Contains(requiredScope))
|
||||
{
|
||||
throw new InvalidOperationException($"Missing required scope '{requiredScope}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Hierarchical match: fine-grained scope "scheduler.runs.read" is satisfied
|
||||
// by OIDC coarse-grained scope "scheduler:read" or "scheduler:admin".
|
||||
// Format: "{service}.{resource}.{action}" -> check "{service}:{action}" and "{service}:admin"
|
||||
var dotParts = requiredScope.Split('.');
|
||||
if (dotParts.Length >= 2)
|
||||
{
|
||||
var service = dotParts[0];
|
||||
var action = dotParts[^1];
|
||||
if (scopes.Contains($"{service}:{action}") || scopes.Contains($"{service}:admin"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Also check "operate" scope for write/manage actions
|
||||
if (action is "write" or "manage" or "preview" && scopes.Contains($"{service}:operate"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Missing required scope '{requiredScope}'.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user