diff --git a/src/Umbraco.Web.BackOffice/Authorization/AdminUsersAuthorizeHandler.cs b/src/Umbraco.Web.BackOffice/Authorization/AdminUsersAuthorizeHandler.cs index 9070246c56..7113fd1b7a 100644 --- a/src/Umbraco.Web.BackOffice/Authorization/AdminUsersAuthorizeHandler.cs +++ b/src/Umbraco.Web.BackOffice/Authorization/AdminUsersAuthorizeHandler.cs @@ -1,14 +1,17 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; using System.Linq; using System.Threading.Tasks; using Umbraco.Core; +using Umbraco.Core.Hosting; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Editors; namespace Umbraco.Web.BackOffice.Authorization { + /// /// if the users being edited is an admin then we must ensure that the current user is also an admin /// diff --git a/src/Umbraco.Web.BackOffice/Authorization/BackOfficeAuthorizationHandler.cs b/src/Umbraco.Web.BackOffice/Authorization/BackOfficeAuthorizationHandler.cs new file mode 100644 index 0000000000..1efaade3af --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Authorization/BackOfficeAuthorizationHandler.cs @@ -0,0 +1,53 @@ +using Microsoft.AspNetCore.Authorization; +using System; +using System.Threading.Tasks; +using Umbraco.Core; +using Umbraco.Core.Security; + +namespace Umbraco.Web.BackOffice.Authorization +{ + /// + /// Ensures authorization is successful for a back office user. + /// + public class BackOfficeAuthorizationHandler : AuthorizationHandler + { + private readonly IBackOfficeSecurityAccessor _backOfficeSecurity; + private readonly IRuntimeState _runtimeState; + + public BackOfficeAuthorizationHandler(IBackOfficeSecurityAccessor backOfficeSecurity, IRuntimeState runtimeState) + { + _backOfficeSecurity = backOfficeSecurity; + _runtimeState = runtimeState; + } + + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, BackOfficeAuthorizeRequirement requirement) + { + if (!IsAuthorized(requirement)) + { + context.Fail(); + } + else + { + context.Succeed(requirement); + } + + return Task.CompletedTask; + } + + private bool IsAuthorized(BackOfficeAuthorizeRequirement requirement) + { + try + { + // if not configured (install or upgrade) then we can continue + // otherwise we need to ensure that a user is logged in + return _runtimeState.Level == RuntimeLevel.Install + || _runtimeState.Level == RuntimeLevel.Upgrade + || _backOfficeSecurity.BackOfficeSecurity?.ValidateCurrentUser(false, requirement.RequireApproval) == ValidateRequestAttempt.Success; + } + catch (Exception) + { + return false; + } + } + } +} diff --git a/src/Umbraco.Web.BackOffice/Authorization/BackOfficeAuthorizeRequirement.cs b/src/Umbraco.Web.BackOffice/Authorization/BackOfficeAuthorizeRequirement.cs new file mode 100644 index 0000000000..684a90891f --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Authorization/BackOfficeAuthorizeRequirement.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Authorization; + +namespace Umbraco.Web.BackOffice.Authorization +{ + /// + /// Authorization requirement for the + /// + public class BackOfficeAuthorizeRequirement : IAuthorizationRequirement + { + public BackOfficeAuthorizeRequirement(bool requireApproval = true) + { + RequireApproval = requireApproval; + } + + public bool RequireApproval { get; } + } +} diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs index 495adc3c4a..a0ae3868d1 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs @@ -110,8 +110,8 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Returns the configuration for the backoffice user membership provider - used to configure the change password dialog /// - /// - [UmbracoBackOfficeAuthorize] + /// + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] public IDictionary GetPasswordConfig(int userId) { return _passwordConfiguration.GetConfiguration(userId != _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id); @@ -157,7 +157,7 @@ namespace Umbraco.Web.BackOffice.Controllers return _umbracoMapper.Map(user); } - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [ValidateAngularAntiForgeryToken] public async Task PostUnLinkLogin(UnLinkLoginModel unlinkLoginModel) { @@ -242,7 +242,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// is valid before the login screen is displayed. The Auth cookie can be persisted for up to a day but the csrf cookies are only session /// cookies which means that the auth cookie could be valid but the csrf cookies are no longer there, in that case we need to re-set the csrf cookies. /// - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [SetAngularAntiForgeryTokens] //[CheckIfUserTicketDataIsStale] // TODO: Migrate this, though it will need to be done differently at the cookie auth level public UserDetail GetCurrentUser() @@ -264,7 +264,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// We cannot user GetCurrentUser since that requires they are approved, this is the same as GetCurrentUser but doesn't require them to be approved /// - [UmbracoBackOfficeAuthorize(redirectToUmbracoLogin: false, requireApproval: false)] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccessWithoutApproval)] [SetAngularAntiForgeryTokens] [Authorize(Policy = AuthorizationPolicies.DenyLocalLoginIfConfigured)] public ActionResult GetCurrentInvitedUser() diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs index d2e7f0d36c..249de5458c 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs @@ -34,6 +34,8 @@ using Microsoft.AspNetCore.Identity; using System.Security.Claims; using Microsoft.AspNetCore.Http; using Umbraco.Web.Security; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.Common.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -231,7 +233,7 @@ namespace Umbraco.Web.BackOffice.Controllers return nestedDictionary; } - [UmbracoBackOfficeAuthorize(Order = 0)] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [HttpGet] public IEnumerable GetGridConfig() { @@ -242,7 +244,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// Returns the JavaScript object representing the static server variables javascript object /// /// - [UmbracoBackOfficeAuthorize(Order = 0)] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [MinifyJavaScriptResult(Order = 1)] public async Task ServerVariables() { @@ -278,7 +280,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// /// - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [HttpPost] public ActionResult LinkLogin(string provider) { @@ -314,7 +316,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// Callback path when the user initiates a link login request from the back office to the external provider from the action /// - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [HttpGet] public async Task ExternalLinkLoginCallback() { diff --git a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs index c22db868b1..a60a773b72 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/ContentController.cs @@ -130,7 +130,8 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// [HttpGet] - [UmbracoBackOfficeAuthorize, OverrideAuthorization] + // TODO: Does this override work? What is best practices for this? + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess), OverrideAuthorization] public bool AllowsCultureVariation() { var contentTypes = _contentTypeService.GetAll(); diff --git a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs index 2005d42b79..7c984e901e 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs @@ -27,6 +27,8 @@ using Umbraco.Web.Common.Exceptions; using Umbraco.Web.Common.Filters; using Umbraco.Web.Models; using Umbraco.Web.Models.ContentEditing; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.Common.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -170,7 +172,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// /// This only works when the user is logged in (partially) /// - [UmbracoBackOfficeAuthorize(redirectToUmbracoLogin: false, requireApproval : true)] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] // TODO: Why is this necessary? This inherits from UmbracoAuthorizedApiController public async Task PostSetInvitedUserPassword([FromBody]string newPassword) { var user = await _backOfficeUserManager.FindByIdAsync(_backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0).ToString()); @@ -236,7 +238,8 @@ namespace Umbraco.Web.BackOffice.Controllers throw HttpResponseException.CreateValidationErrorResponse(ModelState); } - [UmbracoBackOfficeAuthorize] + // TODO: Why is this necessary? This inherits from UmbracoAuthorizedApiController + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [ValidateAngularAntiForgeryToken] public async Task> GetCurrentUserLinkedLogins() { diff --git a/src/Umbraco.Web.BackOffice/Controllers/DashboardController.cs b/src/Umbraco.Web.BackOffice/Controllers/DashboardController.cs index 3f797de9c8..ec2642edb7 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/DashboardController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/DashboardController.cs @@ -20,6 +20,8 @@ using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; using Umbraco.Web.Common.Controllers; using Umbraco.Web.Common.Filters; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.Common.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -28,7 +30,7 @@ namespace Umbraco.Web.BackOffice.Controllers [ValidationFilter] [AngularJsonOnlyConfiguration] // TODO: This could be applied with our Application Model conventions [IsBackOffice] - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] public class DashboardController : UmbracoApiController { private readonly IUmbracoContextAccessor _umbracoContextAccessor; diff --git a/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs b/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs index d83123edc6..40bb8d4122 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/PreviewController.cs @@ -25,6 +25,8 @@ using Umbraco.Web.Services; using Umbraco.Web.Trees; using Umbraco.Web.WebAssets; using Constants = Umbraco.Core.Constants; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.Common.Authorization; namespace Umbraco.Web.BackOffice.Controllers { @@ -66,8 +68,10 @@ namespace Umbraco.Web.BackOffice.Controllers // TODO: This should really be refactored. Redirection/Challenge is part of Authentication, not part of authorization directly // We only use this redirectToUmbracoLogin flag in this one instance. I think this - // should be handled as part of the preview authentication process instead. - [UmbracoBackOfficeAuthorize(redirectToUmbracoLogin: true, requireApproval : false)] + // should be handled as part of the preview authentication process instead. + // I'm actually not even sure this is required? Wouldn't we automatically redirect to the umbraco login screen anyway here? + //[UmbracoBackOfficeAuthorize(redirectToUmbracoLogin: true, requireApproval : false)] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccessWithoutApproval)] [DisableBrowserCache] public ActionResult Index() { @@ -110,7 +114,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// The endpoint that is loaded within the preview iframe /// /// - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] public ActionResult Frame(int id, string culture) { EnterPreview(id); diff --git a/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs b/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs index 080671d3dd..f1a39e1a76 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs @@ -1,6 +1,8 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Umbraco.Web.BackOffice.Filters; using Umbraco.Web.Common.Attributes; +using Umbraco.Web.Common.Authorization; using Umbraco.Web.Common.Controllers; using Umbraco.Web.Common.Filters; @@ -16,7 +18,7 @@ namespace Umbraco.Web.BackOffice.Controllers /// [IsBackOffice] [UmbracoUserTimeoutFilter] - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [DisableBrowserCache] [RequireHttps] [CheckIfUserTicketDataIsStale] diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs index 06e4f1ad4d..81674ca11c 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs @@ -120,6 +120,7 @@ namespace Umbraco.Extensions // NOTE: Even though we are registering these handlers globally they will only actually execute their logic for // any auth defining a matching requirement and scheme. + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -128,6 +129,18 @@ namespace Umbraco.Extensions services.AddAuthorization(options => { + options.AddPolicy(AuthorizationPolicies.BackOfficeAccess, policy => + { + policy.AuthenticationSchemes.Add(Constants.Security.BackOfficeAuthenticationType); + policy.Requirements.Add(new BackOfficeAuthorizeRequirement()); + }); + + options.AddPolicy(AuthorizationPolicies.BackOfficeAccessWithoutApproval, policy => + { + policy.AuthenticationSchemes.Add(Constants.Security.BackOfficeAuthenticationType); + policy.Requirements.Add(new BackOfficeAuthorizeRequirement(false)); + }); + options.AddPolicy(AuthorizationPolicies.AdminUserEditsRequireAdmin, policy => { policy.AuthenticationSchemes.Add(Constants.Security.BackOfficeAuthenticationType); diff --git a/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationAttribute.cs index ed05d831f4..e4aef2a3bc 100644 --- a/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationAttribute.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.BackOffice.Filters /// /// Ensures a special type of authorization filter is ignored. Defaults to . /// - /// The type of authorication filter to override. if null then is used. + /// The type of authorization filter to override. if null then is used. /// /// https://stackoverflow.com/questions/33558095/overrideauthorizationattribute-in-asp-net-5 /// diff --git a/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationFilterProvider.cs b/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationFilterProvider.cs index 6dbf6d747a..9546412270 100644 --- a/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationFilterProvider.cs +++ b/src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationFilterProvider.cs @@ -4,6 +4,7 @@ using Umbraco.Core; namespace Umbraco.Web.BackOffice.Filters { + // TODO: Need to figure out if we need this and what we should be doing public class OverrideAuthorizationFilterProvider : IFilterProvider, IFilterMetadata { public void OnProvidersExecuted(FilterProviderContext context) diff --git a/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs b/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs index e4add40df9..9f0a6ddd1f 100644 --- a/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs +++ b/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs @@ -7,6 +7,8 @@ { public const string UmbracoFeatureEnabled = nameof(UmbracoFeatureEnabled); + public const string BackOfficeAccess = nameof(BackOfficeAccess); + public const string BackOfficeAccessWithoutApproval = nameof(BackOfficeAccessWithoutApproval); public const string UserBelongsToUserGroupInRequest = nameof(UserBelongsToUserGroupInRequest); public const string AdminUserEditsRequireAdmin = nameof(AdminUserEditsRequireAdmin); public const string DenyLocalLoginIfConfigured = nameof(DenyLocalLoginIfConfigured); diff --git a/src/Umbraco.Web.Common/Filters/UmbracoBackOfficeAuthorizeAttribute.cs b/src/Umbraco.Web.Common/Filters/UmbracoBackOfficeAuthorizeAttribute.cs index 94090832bb..1d5a2fc0f1 100644 --- a/src/Umbraco.Web.Common/Filters/UmbracoBackOfficeAuthorizeAttribute.cs +++ b/src/Umbraco.Web.Common/Filters/UmbracoBackOfficeAuthorizeAttribute.cs @@ -1,144 +1,144 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.AspNetCore.Routing; -using System; -using Umbraco.Core; -using Umbraco.Core.Hosting; -using Umbraco.Core.Security; -using Umbraco.Extensions; +//using Microsoft.AspNetCore.Mvc; +//using Microsoft.AspNetCore.Mvc.Filters; +//using Microsoft.AspNetCore.Routing; +//using System; +//using Umbraco.Core; +//using Umbraco.Core.Hosting; +//using Umbraco.Core.Security; +//using Umbraco.Extensions; -namespace Umbraco.Web.Common.Filters -{ - /// - /// Ensures authorization is successful for a back office user. - /// - public class UmbracoBackOfficeAuthorizeAttribute : TypeFilterAttribute - { - /// - /// Default constructor - /// - public UmbracoBackOfficeAuthorizeAttribute() : this(false, false) - { - } +//namespace Umbraco.Web.Common.Filters +//{ +// /// +// /// Ensures authorization is successful for a back office user. +// /// +// public class UmbracoBackOfficeAuthorizeAttribute : TypeFilterAttribute +// { +// /// +// /// Default constructor +// /// +// public UmbracoBackOfficeAuthorizeAttribute() : this(false, false) +// { +// } - /// - /// Constructor with redirect umbraco login behavior - /// - /// - /// +// /// +// /// Constructor with redirect umbraco login behavior +// /// +// /// +// /// - public UmbracoBackOfficeAuthorizeAttribute(bool redirectToUmbracoLogin, bool requireApproval) : base(typeof(UmbracoBackOfficeAuthorizeFilter)) - { - Arguments = new object[] { redirectToUmbracoLogin, requireApproval }; - } +// public UmbracoBackOfficeAuthorizeAttribute(bool redirectToUmbracoLogin, bool requireApproval) : base(typeof(UmbracoBackOfficeAuthorizeFilter)) +// { +// Arguments = new object[] { redirectToUmbracoLogin, requireApproval }; +// } - /// - /// Constructor with redirect url behavior - /// - /// - public UmbracoBackOfficeAuthorizeAttribute(string redirectUrl) : base(typeof(UmbracoBackOfficeAuthorizeFilter)) - { - Arguments = new object[] { redirectUrl }; - } +// /// +// /// Constructor with redirect url behavior +// /// +// /// +// public UmbracoBackOfficeAuthorizeAttribute(string redirectUrl) : base(typeof(UmbracoBackOfficeAuthorizeFilter)) +// { +// Arguments = new object[] { redirectUrl }; +// } - /// - /// Ensures authorization is successful for a back office user. - /// - private class UmbracoBackOfficeAuthorizeFilter : IAuthorizationFilter - { - private readonly bool _requireApproval; +// /// +// /// Ensures authorization is successful for a back office user. +// /// +// private class UmbracoBackOfficeAuthorizeFilter : IAuthorizationFilter +// { +// private readonly bool _requireApproval; - /// - /// Can be used by unit tests to enable/disable this filter - /// - internal static bool Enable = true; - private readonly IHostingEnvironment _hostingEnvironment; - private readonly IUmbracoContextAccessor _umbracoContext; - private readonly IRuntimeState _runtimeState; - private readonly LinkGenerator _linkGenerator; - // TODO: This should really be refactored. Redirection/Challenge is part of Authentication, not part of authorization directly - // We only use this redirectToUmbracoLogin flag in this one instance. I think this - // should be handled as part of the preview authentication process instead. - private readonly bool _redirectToUmbracoLogin; - private string _redirectUrl; +// /// +// /// Can be used by unit tests to enable/disable this filter +// /// +// internal static bool Enable = true; +// private readonly IHostingEnvironment _hostingEnvironment; +// private readonly IUmbracoContextAccessor _umbracoContext; +// private readonly IRuntimeState _runtimeState; +// private readonly LinkGenerator _linkGenerator; +// // TODO: This should really be refactored. Redirection/Challenge is part of Authentication, not part of authorization directly +// // We only use this redirectToUmbracoLogin flag in this one instance. I think this +// // should be handled as part of the preview authentication process instead. +// private readonly bool _redirectToUmbracoLogin; +// private string _redirectUrl; - private UmbracoBackOfficeAuthorizeFilter( - IHostingEnvironment hostingEnvironment, - IUmbracoContextAccessor umbracoContext, - IRuntimeState runtimeState, LinkGenerator linkGenerator, - bool redirectToUmbracoLogin, bool requireApproval, string redirectUrl) - { - _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); - _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); - _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); - _linkGenerator = linkGenerator ?? throw new ArgumentNullException(nameof(linkGenerator)); - _redirectToUmbracoLogin = redirectToUmbracoLogin; - _redirectUrl = redirectUrl; - _requireApproval = requireApproval; - } +// private UmbracoBackOfficeAuthorizeFilter( +// IHostingEnvironment hostingEnvironment, +// IUmbracoContextAccessor umbracoContext, +// IRuntimeState runtimeState, LinkGenerator linkGenerator, +// bool redirectToUmbracoLogin, bool requireApproval, string redirectUrl) +// { +// _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); +// _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); +// _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); +// _linkGenerator = linkGenerator ?? throw new ArgumentNullException(nameof(linkGenerator)); +// _redirectToUmbracoLogin = redirectToUmbracoLogin; +// _redirectUrl = redirectUrl; +// _requireApproval = requireApproval; +// } - /// - /// Default constructor - /// - /// - /// - /// - /// - /// - public UmbracoBackOfficeAuthorizeFilter( - IHostingEnvironment hostingEnvironment, - IUmbracoContextAccessor umbracoContext, - IRuntimeState runtimeState, LinkGenerator linkGenerator, - string redirectUrl) : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, false, false, redirectUrl) - { - } +// /// +// /// Default constructor +// /// +// /// +// /// +// /// +// /// +// /// +// public UmbracoBackOfficeAuthorizeFilter( +// IHostingEnvironment hostingEnvironment, +// IUmbracoContextAccessor umbracoContext, +// IRuntimeState runtimeState, LinkGenerator linkGenerator, +// string redirectUrl) : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, false, false, redirectUrl) +// { +// } - public UmbracoBackOfficeAuthorizeFilter( - IHostingEnvironment hostingEnvironment, - IUmbracoContextAccessor umbracoContext, - IRuntimeState runtimeState, LinkGenerator linkGenerator, - bool redirectToUmbracoLogin, bool requireApproval) : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, redirectToUmbracoLogin, requireApproval, null) - { - } +// public UmbracoBackOfficeAuthorizeFilter( +// IHostingEnvironment hostingEnvironment, +// IUmbracoContextAccessor umbracoContext, +// IRuntimeState runtimeState, LinkGenerator linkGenerator, +// bool redirectToUmbracoLogin, bool requireApproval) : this(hostingEnvironment, umbracoContext, runtimeState, linkGenerator, redirectToUmbracoLogin, requireApproval, null) +// { +// } - public void OnAuthorization(AuthorizationFilterContext context) - { - if (!IsAuthorized()) - { - if (_redirectToUmbracoLogin) - { - _redirectUrl = _linkGenerator.GetBackOfficeUrl(_hostingEnvironment); - } +// public void OnAuthorization(AuthorizationFilterContext context) +// { +// if (!IsAuthorized()) +// { +// if (_redirectToUmbracoLogin) +// { +// _redirectUrl = _linkGenerator.GetBackOfficeUrl(_hostingEnvironment); +// } - if (!_redirectUrl.IsNullOrWhiteSpace()) - { - context.Result = new RedirectResult(_redirectUrl); - } - else - { - context.Result = new ForbidResult(); - } - } - } +// if (!_redirectUrl.IsNullOrWhiteSpace()) +// { +// context.Result = new RedirectResult(_redirectUrl); +// } +// else +// { +// context.Result = new ForbidResult(); +// } +// } +// } - private bool IsAuthorized() - { - if (Enable == false) - return true; +// private bool IsAuthorized() +// { +// if (Enable == false) +// return true; - try - { - // if not configured (install or upgrade) then we can continue - // otherwise we need to ensure that a user is logged in - return _runtimeState.Level == RuntimeLevel.Install - || _runtimeState.Level == RuntimeLevel.Upgrade - || _umbracoContext.UmbracoContext?.Security.ValidateCurrentUser(false, _requireApproval) == ValidateRequestAttempt.Success; - } - catch (Exception) - { - return false; - } - } - } - } -} +// try +// { +// // if not configured (install or upgrade) then we can continue +// // otherwise we need to ensure that a user is logged in +// return _runtimeState.Level == RuntimeLevel.Install +// || _runtimeState.Level == RuntimeLevel.Upgrade +// || _umbracoContext.UmbracoContext?.Security.ValidateCurrentUser(false, _requireApproval) == ValidateRequestAttempt.Success; +// } +// catch (Exception) +// { +// return false; +// } +// } +// } +// } +//} diff --git a/src/Umbraco.Web.Website/Controllers/UmbracoAuthorizedController.cs b/src/Umbraco.Web.Website/Controllers/UmbracoAuthorizedController.cs index b2611848df..ad51d9cb4f 100644 --- a/src/Umbraco.Web.Website/Controllers/UmbracoAuthorizedController.cs +++ b/src/Umbraco.Web.Website/Controllers/UmbracoAuthorizedController.cs @@ -1,4 +1,6 @@ -using Umbraco.Web.Common.Filters; +using Microsoft.AspNetCore.Authorization; +using Umbraco.Web.Common.Authorization; +using Umbraco.Web.Common.Filters; namespace Umbraco.Web.Mvc { @@ -9,10 +11,11 @@ namespace Umbraco.Web.Mvc /// This controller essentially just uses a global UmbracoAuthorizeAttribute, inheritors that require more granular control over the /// authorization of each method can use this attribute instead of inheriting from this controller. /// - [UmbracoBackOfficeAuthorize] + [Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] [DisableBrowserCache] public abstract class UmbracoAuthorizedController : UmbracoController { + // TODO: This controller is not used at all, is there a need for this controller? } }