improve dynamic policy registration to handle possible race conditions

This commit is contained in:
Shaun Walker 2023-01-05 09:43:59 -05:00
parent 67046e9d36
commit 66aa67581f

View File

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Oqtane.Shared; using Oqtane.Shared;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -17,15 +16,15 @@ namespace Oqtane.Security
public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName) public override async Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
{ {
// check static policies first // get policy
policyName = GetPolicyName(policyName); policyName = GetPolicyName(policyName);
var policy = await base.GetPolicyAsync(policyName); var policy = await base.GetPolicyAsync(policyName);
if (policy == null) if (policy == null)
{ {
// policy names must be in the form of "EntityName:PermissionName:Roles" ie. "Module:Edit:Administrators" (roles are comma delimited)
if (policyName.Contains(':')) if (policyName.Contains(':'))
{ {
// policy names must be in the form of "EntityName:PermissionName:Roles" ie. "Module:Edit:Administrators" (roles are comma delimited)
var policySegments = policyName.Split(':'); var policySegments = policyName.Split(':');
if (policySegments.Length >= 3) if (policySegments.Length >= 3)
{ {
@ -35,13 +34,22 @@ namespace Oqtane.Security
{ {
requireEntityId = true; requireEntityId = true;
} }
policy = new AuthorizationPolicyBuilder()
.AddRequirements(new PermissionRequirement(policySegments[0], policySegments[1], policySegments[2], requireEntityId)) // create policy
.Build(); var builder = new AuthorizationPolicyBuilder();
builder.AddRequirements(new PermissionRequirement(policySegments[0], policySegments[1], policySegments[2], requireEntityId));
policy = builder.Build();
// add policy to the AuthorizationOptions // add policy to the AuthorizationOptions
try
{
_options.AddPolicy(policyName, policy); _options.AddPolicy(policyName, policy);
} }
catch
{
// race condition - policy already added by another thread
}
}
} }
} }