Add migration to update ApiClients with centralized authorization scopes

This migration updates the ScopesJson for the ApiClient with Id 91000000-0000-0000-0000-000000000001 to include additional authorization scopes for improved API access control. The Down method reverts the changes if necessary.
This commit is contained in:
Torsten Brendgen
2026-07-09 23:49:01 +02:00
parent dc93ea0813
commit dfd9c16f61
27 changed files with 5617 additions and 34 deletions

View File

@@ -0,0 +1,19 @@
namespace Microsoft.SelfService.Portal.Core.API.Authorization
{
public static class ApiPolicies
{
public const string ConfigurationRead = "ConfigurationRead";
public const string ConfigurationWrite = "ConfigurationWrite";
public const string CredentialRead = "CredentialRead";
public const string CredentialWrite = "CredentialWrite";
public const string CredentialResolve = "CredentialResolve";
public const string DeploymentRead = "DeploymentRead";
public const string DeploymentWrite = "DeploymentWrite";
public const string QueueRead = "QueueRead";
public const string QueueProcess = "QueueProcess";
public const string TemplateRead = "TemplateRead";
public const string TemplateWrite = "TemplateWrite";
public const string TokenManage = "TokenManage";
public const string TokenAdmin = "TokenAdmin";
}
}

View File

@@ -0,0 +1,19 @@
namespace Microsoft.SelfService.Portal.Core.API.Authorization
{
public static class ApiScopes
{
public const string ConfigurationRead = "configuration.read";
public const string ConfigurationWrite = "configuration.write";
public const string CredentialRead = "credential.read";
public const string CredentialWrite = "credential.write";
public const string CredentialResolve = "credential.resolve";
public const string DeploymentRead = "deployment.read";
public const string DeploymentWrite = "deployment.write";
public const string QueueRead = "queue.read";
public const string QueueProcess = "queue.process";
public const string TemplateRead = "template.read";
public const string TemplateWrite = "template.write";
public const string TokenManage = "token.manage";
public const string TokenAdmin = "token.admin";
}
}

View File

@@ -0,0 +1,50 @@
using Microsoft.AspNetCore.Authorization;
namespace Microsoft.SelfService.Portal.Core.API.Authorization
{
public static class AuthorizationServiceCollectionExtensions
{
public static IServiceCollection AddSelfServicePortalAuthorization(this IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
AddScopePolicy(options, ApiPolicies.ConfigurationRead, ApiScopes.ConfigurationRead, ApiScopes.ConfigurationWrite);
AddScopePolicy(options, ApiPolicies.ConfigurationWrite, ApiScopes.ConfigurationWrite);
AddScopePolicy(options, ApiPolicies.CredentialRead, ApiScopes.CredentialRead, ApiScopes.CredentialWrite, ApiScopes.CredentialResolve);
AddScopePolicy(options, ApiPolicies.CredentialWrite, ApiScopes.CredentialWrite);
AddScopePolicy(options, ApiPolicies.CredentialResolve, ApiScopes.CredentialResolve);
AddScopePolicy(options, ApiPolicies.DeploymentRead, ApiScopes.DeploymentRead, ApiScopes.DeploymentWrite);
AddScopePolicy(options, ApiPolicies.DeploymentWrite, ApiScopes.DeploymentWrite);
AddScopePolicy(options, ApiPolicies.QueueRead, ApiScopes.QueueRead, ApiScopes.QueueProcess);
AddScopePolicy(options, ApiPolicies.QueueProcess, ApiScopes.QueueProcess);
AddScopePolicy(options, ApiPolicies.TemplateRead, ApiScopes.TemplateRead, ApiScopes.TemplateWrite);
AddScopePolicy(options, ApiPolicies.TemplateWrite, ApiScopes.TemplateWrite);
AddScopePolicy(options, ApiPolicies.TokenManage, ApiScopes.TokenManage, ApiScopes.TokenAdmin);
AddScopePolicy(options, ApiPolicies.TokenAdmin, ApiScopes.TokenAdmin);
});
return services;
}
private static void AddScopePolicy(AuthorizationOptions options, string policyName, params string[] acceptedScopes)
{
options.AddPolicy(policyName, policy => policy.RequireAssertion(context =>
{
if (context.User.Identity?.IsAuthenticated != true)
{
return false;
}
var tokenScopes = context.User.FindAll("scope").Select(claim => claim.Value).ToList();
if (tokenScopes.Count == 0)
{
return true;
}
return acceptedScopes.Any(scope => tokenScopes.Contains(scope, StringComparer.OrdinalIgnoreCase));
}));
}
}
}