diff --git a/src/Umbraco.Web.Common/Filters/UmbracoMemberAuthorizeFilter.cs b/src/Umbraco.Web.Common/Filters/UmbracoMemberAuthorizeFilter.cs index b0a640b230..249dd6a1d2 100644 --- a/src/Umbraco.Web.Common/Filters/UmbracoMemberAuthorizeFilter.cs +++ b/src/Umbraco.Web.Common/Filters/UmbracoMemberAuthorizeFilter.cs @@ -1,6 +1,10 @@ using System.Collections.Generic; using System.Threading.Tasks; + +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Authorization; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Security; @@ -42,6 +46,12 @@ namespace Umbraco.Cms.Web.Common.Filters public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { + // Allow Anonymous skips all authorization + if (HasAllowAnonymous(context)) + { + return; + } + IMemberManager memberManager = context.HttpContext.RequestServices.GetRequiredService(); if (!await IsAuthorizedAsync(memberManager)) @@ -51,6 +61,32 @@ namespace Umbraco.Cms.Web.Common.Filters } } + /// + /// Copied from https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/Authorization/AuthorizeFilter.cs + /// + private bool HasAllowAnonymous(AuthorizationFilterContext context) + { + var filters = context.Filters; + for (var i = 0; i < filters.Count; i++) + { + if (filters[i] is IAllowAnonymousFilter) + { + return true; + } + } + + // When doing endpoint routing, MVC does not add AllowAnonymousFilters for AllowAnonymousAttributes that + // were discovered on controllers and actions. To maintain compat with 2.x, + // we'll check for the presence of IAllowAnonymous in endpoint metadata. + var endpoint = context.HttpContext.GetEndpoint(); + if (endpoint?.Metadata?.GetMetadata() != null) + { + return true; + } + + return false; + } + private async Task IsAuthorizedAsync(IMemberManager memberManager) { if (AllowMembers.IsNullOrWhiteSpace())