Execute AuthenticateAsync and AuthorizeAsync on nested requests
This commit is contained in:
@@ -2,8 +2,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization.Policy;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Cms.Web.BackOffice.Extensions
|
||||
{
|
||||
@@ -15,8 +19,35 @@ namespace Umbraco.Cms.Web.BackOffice.Extensions
|
||||
/// <returns>Whether the user is authenticated or not.</returns>
|
||||
internal static async Task<bool> InvokeAuthorizationFiltersForRequest(this ControllerContext controllerContext, ActionContext actionContext)
|
||||
{
|
||||
|
||||
var actionDescriptor = controllerContext.ActionDescriptor;
|
||||
|
||||
var metadataCollection = new EndpointMetadataCollection(actionDescriptor.EndpointMetadata.Union(new []{actionDescriptor}));
|
||||
|
||||
var authorizeData = metadataCollection.GetOrderedMetadata<IAuthorizeData>();
|
||||
var policyProvider = controllerContext.HttpContext.RequestServices.GetRequiredService<IAuthorizationPolicyProvider>();
|
||||
var policy = await AuthorizationPolicy.CombineAsync(policyProvider, authorizeData);
|
||||
if (policy is not null)
|
||||
{
|
||||
var policyEvaluator = controllerContext.HttpContext.RequestServices.GetRequiredService<IPolicyEvaluator>();
|
||||
var authenticateResult = await policyEvaluator.AuthenticateAsync(policy, controllerContext.HttpContext);
|
||||
|
||||
if (!authenticateResult.Succeeded)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO this is super hacky, but we rely on the FeatureAuthorizeHandler can still handle endpoints
|
||||
// (The way before .NET 5). The .NET 5 way would need to use han http context, for the "inner" request
|
||||
// with the nested controller
|
||||
var resource = new Endpoint(null,metadataCollection, null);
|
||||
var authorizeResult = await policyEvaluator.AuthorizeAsync(policy, authenticateResult, controllerContext.HttpContext, resource);
|
||||
if (!authorizeResult.Succeeded)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var filters = actionDescriptor.FilterDescriptors;
|
||||
var filterGrouping = new FilterGrouping(filters, controllerContext.HttpContext.RequestServices);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.Trees;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Trees;
|
||||
@@ -18,7 +19,6 @@ using Umbraco.Cms.Web.Common.Filters;
|
||||
using Umbraco.Cms.Web.Common.ModelBinders;
|
||||
using Umbraco.Extensions;
|
||||
using static Umbraco.Cms.Core.Constants.Web.Routing;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
{
|
||||
@@ -150,11 +150,11 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
|
||||
foreach (var t in trees)
|
||||
{
|
||||
var nodeResult = await TryGetRootNode(t, queryStrings);
|
||||
if (!(nodeResult.Result is null))
|
||||
if (nodeResult != null && nodeResult.Result is not null)
|
||||
{
|
||||
return nodeResult.Result;
|
||||
}
|
||||
var node = nodeResult.Value;
|
||||
var node = nodeResult?.Value;
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
|
||||
@@ -8,5 +8,9 @@ namespace Umbraco.Cms.Web.Common.Authorization
|
||||
/// </summary>
|
||||
public class FeatureAuthorizeRequirement : IAuthorizationRequirement
|
||||
{
|
||||
public FeatureAuthorizeRequirement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user