Пользовательский AuthorizeAttribute в WebApi OData EntitySetController

Я создал настраиваемый атрибут авторизации для обработки моих настраиваемых разрешений на контроллере odata WebAPI, унаследованном от EntitySetController, вот код для моего атрибута

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public class RequirePermissionsAttribute : System.Web.Http.AuthorizeAttribute
{
    public Permissions[] Permissions { get; set; }


    public RequirePermissionsAttribute()
    { }

    public RequirePermissionsAttribute(params Permissions[] permissions)
    {
        this.Permissions = permissions;
    }

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
       // Custom  authorization logic
    }

Теперь я пытаюсь добавить этот атрибут в метод Get(), он вызывается

public class ItemsController : EntitySetController<Item, Guid>
{
   [EnableQuery(MaxExpansionDepth = 5)]
   [RequirePermissionsAttribute(Permissions.ViewAll)]
   public override IQueryable<Item> Get()
   {
     //Code go here
   }
}

Но когда я добавляю тот же атрибут в CreateEntity(), он никогда не вызывается

[RequirePermissionsAttribute(Permissions.Add)]
protected override Item CreateEntity(Item item)
{
  // Create item
}

Любая помощь приветствуется


person Islam El-Khayat    schedule 25.12.2014    source источник


Ответы (2)


Вы должны использовать свой атрибут как RequirePermissions без хвостового слова «Атрибут», поэтому измените свой код, чтобы он был похож на этот

[RequirePermissions(Permissions.Add)] protected override Item CreateEntity(Item item) { // Create item }

person Omar.Alani    schedule 25.12.2014

ислам

Из исходных кодов WebAPI внутренняя виртуальная функция CreateEntity() вызывается в запросе POST. Вот исходники в EntitySetController:

public virtual HttpResponseMessage Post([FromBody] TEntity entity)
{
    TEntity createdEntity = CreateEntity(entity);
    TKey entityKey = GetKey(entity);
    return EntitySetControllerHelpers.PostResponse(this, createdEntity, entityKey);
}

Я использую ваши примеры кодов и отправляю запрос POST, CreateEntity() можно вызывать как:

POST ~/odata/Items

Content-type: application/json

{"Id":"9daf653f-212c-42e3-80a4-4778e445c092"}

введите здесь описание изображения

Однако, если вы хотите получить правильный ответ, вы должны переопределить GetKey(), потому что GetKey() вызывается после CreateEntity() в методе Post(). Та же информация также упоминается в примечаниях CreateEntity(), как показано ниже:

введите здесь описание изображения

Образец теста

Я создаю следующие две функции в ItemsController:

protected override Guid GetKey(Item entity)
{
    return entity.Id;
}

[RequirePermissionsAttribute(Permissions.Add)]
protected override Item CreateEntity(Item item)
{
    // Create item
    return item;
}

И отправьте тот же запрос POST, упомянутый выше, я могу получить следующий ответ:

HTTP/1.1 201 Created
Cache-Control: no-cache
.....
Content-Length: 124

{
  "odata.metadata":"http://localhost:47794/odata/$metadata#Items/@Element","Id":"9daf653f-212c-42e3-80a4-4778e445c092"
}

Надеюсь, это поможет вам. Спасибо.

person Sam Xu    schedule 04.01.2015