Спеціальна авторизація в Asp.net WebApi - який безлад?


113

Я читаю з декількох ресурсів (книги та відповіді) про авторизацію в WebApi.

Припустимо, я хочу додати спеціальний атрибут, який дозволяє отримати доступ лише для певних користувачів:

Справа №1

Я бачив такий підхід , що переосмислює OnAuthorization , який задає відповідь, якщо щось не так

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 public override void OnAuthorization(HttpActionContext actionContext)
  {
   if ( /*check if user OK or not*/)
   {
     actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
   }
  }
}

Справа №2

Але я також бачив подібний приклад, який також переважає, OnAuthorizationале із закликом base:

public override void OnAuthorization(HttpActionContext actionContext) 
{ 
  base.OnAuthorization(actionContext);

    // If not authorized at all, don't bother

    if (actionContext.Response == null)  
     {
      //...
     }
}

Потім ви перевіряєте HttpActionContext.Response, встановлено чи ні. Якщо його не встановлено, це означає, що запит авторизований і користувач нормально

Справа №3

Але я також бачив такий підхід, що переважає IsAuthorized :

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 protected override bool IsAuthorized(HttpActionContext context)
  {
   if ( /*check if user OK or not*/)
   {
    return true;// or false
   }
  }
}

Справа №4

І тоді я побачив подібний приклад, але з викликом base.IsAuthorized (контекст):

protected override bool IsAuthorized(HttpActionContext context)
{
 if (something1 && something2 && base.IsAuthorized(context)) //??
 return true;
 return false;
}

І ще одна річ

І нарешті Домінік сказав тут :

Вам не слід перекривати OnAuthorization - тому що вам не вистачить [AllowAnonymous] обробки.

Запитання

  • 1) Які методи я повинен використовувати: IsAuthorizedабо OnAuthorization? (або коли використовувати)

  • 2) коли я повинен викликати base.IsAuthorized orбазу. Про авторизацію`?

  • 3) Це, як вони його побудували? що якщо відповідь недійсна, то все нормально? (випадок №2)

NB

Зауважте, я використовую (і хочу використовувати) лише те, AuthorizeAttributeщо вже успадковане AuthorizationFilterAttribute

Чому?

Тому що я на першому етапі: http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

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

У будь-якому випадку я запитую через розширений атрибут Авторизація.


Що потрібно, щоб замінити атрибут "Авторизувати"? Якої корисної справи ви хочете досягти? Якщо вам потрібно дозволити доступ для певних користувачів, чому б не використовувати атрибут [Authorize (Users = "Admin")], як це?
Taiseer Joudeh

1
@TaiseerJoudeh Наприклад, спробуйте авторизувати користувачів між 10:00 та 12:00 (налаштовується). Ви не можете зробити це за допомогою звичайних ролей та авторизованих attr. ви повинні зробити свою власну логіку
Рой Намір

Відповіді:


93

Які методи я повинен використовувати: IsAuthorized або OnAuthorization? (або коли використовувати)

Ви продовжите, AuthorizationFilterAttributeякщо ваша логіка авторизації не буде залежати від встановленої особи та ролей. Для авторизації, пов’язаної з користувачем, ви будете розширювати та використовувати AuthorizeAttribute. У першому випадку ви переможете OnAuthorization. В останньому випадку ви переможете IsAuthorized. Як видно з вихідного коду цих атрибутів, ви OnAuthorizationпозначаєте віртуальне для вас, якщо ви походите з цього AuthorizationFilterAttribute. З іншого боку, IsAuthorizedметод позначений віртуальним в AuthorizeAttribute. Я вважаю, що це хороший вказівник на передбачуване використання.

коли я повинен викликати base.IsAuthorized або base.OnAuthorization?

Відповідь на це питання полягає у тому, як загалом працює ОО. Якщо ви перекриєте метод, ви можете або повністю надати нову реалізацію, або повернути назад реалізацію, яку надає батько, та покращити поведінку. Наприклад, візьміть випадок IsAuthorized(HttpActionContext). Поведінка базового класу полягає у тому, щоб перевірити користувача / роль щодо того, що вказано у фільтрі та встановленої ідентичності. Скажімо, ви хочете зробити все це, але крім того, ви хочете перевірити щось інше, може базуватися на заголовку запиту або щось інше. У такому випадку ви можете надати такий перебір.

protected override bool IsAuthorized(HttpActionContext actionContext)
{
    bool isAuthroized = base.IsAuthorized(actionContext);
    // Here you look at the header and do your additional stuff based on actionContext
    // and store the result in isRequestHeaderOk
    // Then, you can combine the results
    // return isAuthorized && isRequestHeaderOk;
}

Вибачте, але не розумію вашого Q3. До речі, фільтр авторизації існує вже давно, і люди використовують його для будь-яких речей, а іноді й неправильно.

І ще одна річ. І нарешті, тут знайшов цей хлопець, який сказав: Не слід перекривати OnAuthorization - тому що ви б пропустили [AllowAnonymous] обробку.

Хлопець, який сказав, що це Бог контролю доступу - Домінік. Очевидно, це буде правильно. Якщо ви подивитесь на реалізацію OnAuthorization(скопійовано нижче),

public override void OnAuthorization(HttpActionContext actionContext)
{
    if (actionContext == null)
    {
        throw Error.ArgumentNull("actionContext");
    }

    if (SkipAuthorization(actionContext))
    {
        return;
    }

    if (!IsAuthorized(actionContext))
    {
        HandleUnauthorizedRequest(actionContext);
    }
}

call to SkipAuthorization- це частина, яка забезпечує застосування AllowAnonymousфільтрів, тобто авторизація пропускається. Якщо ви скасуєте цей метод, ви втратите таку поведінку. Насправді, якби ви вирішили базувати свою авторизацію на користувачах / ролях, ви б вирішили виходити з цього місця AuthorizeAttribute. Єдиним правильним варіантом, що залишився для вас на той момент, буде переосмислення, IsAuthorizedа не вже переосмислений OnAuthorization, хоча технічно це можна зробити і.

PS. У веб-API ASP.NET є ще один фільтр під назвою фільтр автентифікації. Ідея полягає в тому, що ви використовуєте це для автентифікації та фільтра авторизації для авторизації, як вказує назва. Однак є чимало прикладів, коли ця межа підмітається. Багато прикладів фільтрів авторизації виконають певну автентифікацію. У будь-якому разі, якщо у вас є час і хочете зрозуміти трохи більше, погляньте на цю статтю MSDN . Відмова: Це було написано мною.


Дякую ще раз, але якщо я читаю між рядками, IsAuthentication називається викликом за допомогою OnAuthirization, то чому б не замінити OnAuthorization та виклик base.OnAuthorization та перевірити відповідь?
Royi Namir

Ви впевнені, можете, якщо це те, що ви хочете.
Бадрі

У третьому запитанні я мав на увазі: після запуску базової функції - base.OnAuthorization, наприклад, чи єдиний спосіб перевірити, чи вдалося це - перевірити властивість Response ?, ps приклади з вашої книги :-)
Рой Намір

Так, зазвичай ви шукаєте код статусу 401, але не нульовий, наскільки я знаю. До речі, я не пам’ятаю, щоб писати про переоцінку OnAuthorizationу своїй книзі. Я впевнений, що не писав би про перевірку відповіді на null, тому що це перший раз, коли я чую про це :)
Бадрі

Так, я заплутався в іншій книзі. Я читаю 3 книги одночасно: securty (ваша), практична (ваша) та webapi pro (Tugberk's, Zeitler, Ali). Як ви бачите - вони це зробили там: i.stack.imgur.com/LNGi4.jpg - вони просто перевірили, чи немає, тож я повинен перевірити нульові чи помилкові коди?
Рой Намір

18

Гаразд, я пропоную зробити наступне, припускаючи, що ви використовуєте маркери носія OAuth для захисту свого веб-API, і ви встановлюєте дозволений час як претензія для користувача, коли ви видали маркер. Більше про аутентифікацію на основі лексем можна прочитати тут

  1. Створіть CustomAuthorizeAttribute, який походить від AuthorizationFilterAttribute
  2. метод переосмислення OnAuthorizationAsyncта використання зразкового коду нижче:

     public class CustomAuthorizeAttribute : AuthorizationFilterAttribute
    {
    
        public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
        {
    
            var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
    
            if (!principal.Identity.IsAuthenticated)
            {
                return Task.FromResult<object>(null);
            }
    
            var userName = principal.FindFirst(ClaimTypes.Name).Value;
            var userAllowedTime = principal.FindFirst("userAllowedTime").Value;
    
            if (currentTime != userAllowedTime)
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Not allowed to access...bla bla");
                return Task.FromResult<object>(null);
            }
    
            //User is Authorized, complete execution
            return Task.FromResult<object>(null);
    
        }
    }
  3. Тепер у своїх контролерах ви використовуєте атрибут CustomAuthorize для захисту своїх контролерів за допомогою цієї логіки авторизації.

1
Дякую. Але я зараз використовую те, AuthorizeAttributeщо успадковує, AuthorizationFilterAttributeі - також для навчання, я спеціально запитав, який метод я повинен використовувати, і про відповідь має вміст чи нічого не
важливо

3

ASP.NET v5 представив абсолютно нову систему авторизації. Для тих, хто збирається використовувати .NET 5, я б запропонував перейти в Microsoft.AspNet.Authorization.

В значній мірі він заповнює безлад, викликаний збереженням і System.Web.Http.Authorizeта, System.Web.Mvc.Authorizeі інших старих реалізацій аутентифікації.

Він забезпечує дуже хорошу абстракцію типів дій (Створення, читання, оновлення, видалення), ресурсів, ролей, претензій, переглядів, спеціальних вимог та дозволяє створювати власні обробники, поєднуючи будь-яке з перерахованого. Крім того, ці обробники можуть використовуватися і в комбінації.

В авторизації ASP.NET v5 тепер передбачена проста декларативна роль та більш базова модель, заснована на політиці, де авторизація виражається в вимогах, а обробники оцінюють претензії користувачів на потреби. Імперативні перевірки можуть ґрунтуватися на простих правилах чи правилах, які оцінюють ідентичність користувача, і властивості ресурсу, до якого користувач намагається отримати доступ.


14
Добре знати, але зовсім не відповідає на питання.
Zero3
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.