Создаем ActionFilterAttribute для фильтрации доступа к ресурсам

И так нужно проверить существование ресурса и принадлежит ли данный ресурс пользователю. В случае не выполнения одного из условий бросаем исключение NotFoundException.

 

using InfoShop.Infrastructure;
using System;
using System.Linq;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace WebApp.Controllers
{
    public class UserFilteredAttribute : ActionFilterAttribute
    {
        private Type _domainType;
        private string _paramName;
        private string[] _itemIdPropertyPath;

        public UserFilteredAttribute(Type domainType, string paramName, params string[] itemIdPropertyPath)
        {
            if (domainType == null)
                throw new ArgumentException("domain must not null.");
            if (paramName == null)
                throw new ArgumentException("paramName must not null.");
            _domainType = domainType;
            _paramName = paramName;
            _itemIdPropertyPath = itemIdPropertyPath;
        }

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            object itemId = GetItemId(actionContext);
            if (!(itemId is int || itemId is int?))
                throw new NotFoundException($"ItemId should be int or int?.");

            var item = GetItem((int)itemId);
            if (item == null)
                throw new NotFoundException($"Item with id {itemId} not found");

            var userItem = item as IUserIdModel;
            if (userItem != null)
            {
                var user = GetUser(actionContext);
                if (userItem.UserId != user.Id)
                    throw new NotFoundException($"Item with id {itemId} not found");
            }

        }

        private User GetUser(HttpActionContext actionContext)
        {
            var controller = actionContext.ControllerContext.Controller as IUserHolder;
            if (controller == null)
                throw new Exception("Controller does not implement IUserHolder interface.");
            return controller.User;
        }

        private object GetItem(int itemId)
        {
            if (!typeof(IIdModel).IsAssignableFrom(_domainType))
                throw new Exception($"Domain should be implemented {nameof(IIdModel)}");
            Type iBaseRepositoryType = typeof(IBaseRepository<>).MakeGenericType(_domainType);
            Type iDomainRepositoryType = Assembly.GetAssembly(iBaseRepositoryType)
                 .GetTypes().FirstOrDefault(p => iBaseRepositoryType.IsAssignableFrom(p) && p.IsInterface);
            var domainRepositoryType = ServiceLocator.GetService(iDomainRepositoryType);
            var item = iBaseRepositoryType.GetMethod(nameof(IBaseRepository<IdModel>.GetItem)).Invoke(domainRepositoryType, new object[] { itemId });
            return item;

        }

        private object GetItemId(HttpActionContext actionContext)
        {
            var param = actionContext.ActionDescriptor.GetParameters().FirstOrDefault(x => x.ParameterName == _paramName);
            if (param == null)
                throw new Exception($"Param with paramName {_paramName} not found.");

            object itemId = actionContext.ActionArguments[_paramName];
            if (!ReflectorUtil.IsPrimitive(param.ParameterType))
            {
                if (_itemIdPropertyPath == null || _itemIdPropertyPath.Length == 0)
                    throw new Exception("idPropertyPath should not has elements.");

                try
                {
                    itemId = ReflectorUtil.GetPropValue(itemId, string.Join(",", _itemIdPropertyPath));
                }
                catch (Exception)
                {
                    throw new NotFoundException("Item not found");
                }
            }
            if (itemId == null)
            {
                throw new NotFoundException("Item not found");
            }
            return itemId;
        }
    }
}

Используем так:

        // GET api/items/5
        [UserFilteredAttrbute(typeof(ProductDomain), "id")]
        public string GetItem(int id)
        {
            return $"item with id: {id}";
        }