using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; namespace Core.Cerberos.Adapters.Attributes { /// /// Custom authorization attribute that checks if the user has any of the required permissions. /// [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public class PermissionAttribute : AuthorizeAttribute, IAuthorizationFilter { private readonly string _requiredPermissions; /// /// Initializes a new instance of the class. /// /// The array of permissions required to access the resource. public PermissionAttribute(string requiredPermissions) { _requiredPermissions = requiredPermissions; } /// /// Called during the authorization process to determine if the user has any of the required permissions. /// /// The context in which the authorization filter operates. public void OnAuthorization(AuthorizationFilterContext context) { try { var hasPermission = false; var servicePermissionsList = _requiredPermissions.Replace(" ", "").Split(',').ToList(); var servicePermissions = servicePermissionsList.Select(s => new Permission { Name = s.Substring(0, s.IndexOf('.')), AccessLevel = s.Substring(s.IndexOf('.') + 1), }); var userPermissionsList = context.HttpContext.User.Claims .Where(c => c.Type == "permissions") .Select(c => c.Value) .ToList(); var userPermissions = userPermissionsList.Select(s => new Permission { Name = s.Substring(0, s.IndexOf('.')), AccessLevel = s.Substring(s.IndexOf('.') + 1), }); foreach (var servicePermission in servicePermissions) { hasPermission = userPermissions .Where(up => up.Name == servicePermission.Name && up.AccessLevel == "All" || up.Name == servicePermission.Name && up.AccessLevel == servicePermission.AccessLevel) .Count() > 0 ? true : false; if (hasPermission) break; } if (!hasPermission) context.Result = new UnauthorizedResult(); } catch (Exception ex) { context.Result = new UnauthorizedResult(); } } } }