using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Security.Principal; using System.Threading.Tasks; namespace GreenTree.Strohrmann.ERP.Services.Authorization { public class DefaultAuthorizationHandler : AuthorizationHandler { #region DI fields // The current authorization service private readonly IAuthorizationService _authorizationService; private readonly IHttpContextAccessor _httpContextAccessor; #endregion #region Properties /// /// The administration Options /// public AdministrationOptions Options { get; set; } #endregion #region DI Ctor /// /// Initializes a new instance of the DefaultAuthorizationHandler class /// /// The dependent authorization serivce. /// The global administration options. public DefaultAuthorizationHandler( IAuthorizationService authorizationService, IConfiguration configuration, IHttpContextAccessor httpContextAccessor) { _authorizationService = authorizationService; var administrationOptions = configuration.GetSection("AdministrationOptions").Get(); if (administrationOptions == null) throw new Exception("The appsettings.json does not contain administration options."); Options = administrationOptions; _httpContextAccessor = httpContextAccessor; } #endregion #region Implementation AuthorizationHandler /// /// Handle the current requirement for a specific resource /// /// The authorization context. /// The requirement. /// Returns a succeeded or failed task if the user is authorized for the required resource. protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, DefaultAuthorizationPolicy requirement) { // Check if the checked requirement is the default policy and allow access when authenticated if (requirement.Policy == String.Empty && context.User.Identity.IsAuthenticated) { context.Succeed(requirement); return Task.CompletedTask; } // Check admin state of user var isAdmin = context.User.Identity.Name == Options.Administrator; if (isAdmin) { context.Succeed(requirement); return Task.CompletedTask; } // Process the UserHasPolicy check from the current authorization service var isAuthorized = _authorizationService.UserHasPolicy(context.User.Identity, requirement.Policy); if (isAuthorized) context.Succeed(requirement); else context.Fail(); return Task.CompletedTask; } #endregion } }