Skip to content

Commit 72bef88

Browse files
MigaroezZeegaan
authored andcommitted
Merge commit from fork
1 parent a3ede67 commit 72bef88

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed

src/Umbraco.Cms.Api.Management/DependencyInjection/BackOfficeAuthPolicyBuilderExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ internal static IUmbracoBuilder AddAuthorizationPolicies(this IUmbracoBuilder bu
2929
builder.Services.AddSingleton<IAuthorizationHandler, UserGroupPermissionHandler>();
3030
builder.Services.AddSingleton<IAuthorizationHandler, UserPermissionHandler>();
3131
builder.Services.AddSingleton<IAuthorizationHandler, AllowedApplicationHandler>();
32+
builder.Services.AddSingleton<IAuthorizationHandler, BackOfficeHandler>();
3233

3334
builder.Services.AddAuthorization(CreatePolicies);
3435
return builder;
@@ -46,7 +47,7 @@ void AddAllowedApplicationsPolicy(string policyName, params string[] allowedClai
4647
options.AddPolicy(AuthorizationPolicies.BackOfficeAccess, policy =>
4748
{
4849
policy.AuthenticationSchemes.Add(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
49-
policy.RequireAuthenticatedUser();
50+
policy.Requirements.Add(new BackOfficeRequirement());
5051
});
5152

5253
options.AddPolicy(AuthorizationPolicies.RequireAdminAccess, policy =>

src/Umbraco.Cms.Api.Management/Security/Authorization/DenyLocalLogin/DenyLocalLoginHandler.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.AspNetCore.Authorization;
22
using Microsoft.AspNetCore.Authorization.Infrastructure;
3+
using Umbraco.Cms.Api.Management.Security.Authorization.User;
34

45
namespace Umbraco.Cms.Api.Management.Security.Authorization.DenyLocalLogin;
56

@@ -24,12 +25,12 @@ protected override Task<bool> IsAuthorized(AuthorizationHandlerContext context,
2425

2526
if (isDenied is false)
2627
{
27-
// AuthorizationPolicies.BackOfficeAccess policy adds this requirement by policy.RequireAuthenticatedUser()
28+
// AuthorizationPolicies.BackOfficeAccess policy adds this requirement by policy.Requirements.Add(new BackOfficeRequirement());
2829
// Since we want to "allow anonymous" for some endpoints (i.e. BackOfficeController.Login()), it is necessary to succeed this requirement
29-
IEnumerable<DenyAnonymousAuthorizationRequirement> denyAnonymousUserRequirements = context.PendingRequirements.OfType<DenyAnonymousAuthorizationRequirement>();
30-
foreach (DenyAnonymousAuthorizationRequirement denyAnonymousUserRequirement in denyAnonymousUserRequirements)
30+
IEnumerable<BackOfficeRequirement> backOfficeRequirements = context.PendingRequirements.OfType<BackOfficeRequirement>();
31+
foreach (BackOfficeRequirement backOfficeRequirement in backOfficeRequirements)
3132
{
32-
context.Succeed(denyAnonymousUserRequirement);
33+
context.Succeed(backOfficeRequirement);
3334
}
3435
}
3536

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Umbraco.Cms.Core.Security;
3+
4+
namespace Umbraco.Cms.Api.Management.Security.Authorization.User;
5+
6+
/// <summary>
7+
/// Ensures authorization is successful for a back office user.
8+
/// </summary>
9+
public class BackOfficeHandler : MustSatisfyRequirementAuthorizationHandler<BackOfficeRequirement>
10+
{
11+
private readonly IBackOfficeSecurityAccessor _backOfficeSecurity;
12+
13+
public BackOfficeHandler(IBackOfficeSecurityAccessor backOfficeSecurity)
14+
{
15+
_backOfficeSecurity = backOfficeSecurity;
16+
}
17+
18+
protected override Task<bool> IsAuthorized(AuthorizationHandlerContext context, BackOfficeRequirement requirement)
19+
{
20+
21+
if (context.HasFailed is false && context.HasSucceeded is true)
22+
{
23+
return Task.FromResult(true);
24+
}
25+
26+
if (!_backOfficeSecurity.BackOfficeSecurity?.IsAuthenticated() ?? false)
27+
{
28+
return Task.FromResult(false);
29+
}
30+
31+
var userApprovalSucceeded = !requirement.RequireApproval ||
32+
(_backOfficeSecurity.BackOfficeSecurity?.CurrentUser?.IsApproved ?? false);
33+
return Task.FromResult(userApprovalSucceeded);
34+
}
35+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
3+
namespace Umbraco.Cms.Api.Management.Security.Authorization.User;
4+
5+
/// <summary>
6+
/// Authorization requirement for the <see cref="BackOfficeHandler" />.
7+
/// </summary>
8+
public class BackOfficeRequirement : IAuthorizationRequirement
9+
{
10+
/// <summary>
11+
/// Initializes a new instance of the <see cref="BackOfficeRequirement" /> class.
12+
/// </summary>
13+
/// <param name="requireApproval">Flag for whether back-office user approval is required.</param>
14+
public BackOfficeRequirement(bool requireApproval = true) => RequireApproval = requireApproval;
15+
16+
/// <summary>
17+
/// Gets a value indicating whether back-office user approval is required.
18+
/// </summary>
19+
public bool RequireApproval { get; }
20+
}

0 commit comments

Comments
 (0)