Пользовательский фильтр авторизации в .NET Core API

Я хочу авторизовать пользователей перед доступом к каким-либо данным с помощью моего основного API, поэтому я попытался использовать аутентификацию JWT. Я успешно сгенерировал токен при входе в систему с помощью api и сохранил этот токен на стороне клиента в сеансе, теперь, когда пользователь хочет получить доступ к любым данным с помощью api, я отправлю этот токен в заголовке в api, и я хочу проверить этот токен JWT с помощью настраиваемого фильтра авторизации. Я создал настраиваемый фильтр авторизации и применил его к своему API GetMenu, и я могу успешно проверить этот токен, но после проверки токена в фильтре авторизации он не попадает в мой GetMenu api.

Вот мой код AccountController:

[Filters.Authorization]
[AllowAnonymous]
[HttpPost]
[Route("GetMenu")]
public IActionResult GetMenu(string clientid, int rolecode, string repcode)
{
    //further process
}

Вот мой код авторизации Filters.Authorization:

public class Authorization: AuthorizeAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext filterContext)
    {
        if (!ValidateToken(filterContext.HttpContext.Request.Headers["token"]))
        {
            filterContext.Result = new UnauthorizedResult();
        }
    }
}

У меня есть точки останова на методе OnAuthorization и на API GetMenu. Я вызываю свой GetMenu api через почтальона для тестирования, он успешно попадает в метод OnAuthorization в фильтрах. Авторизация и проверка моего токена JWT и отображает код состояния: 200 в почтальоне, но после успешной проверки токена он должен нажать на GetMenu api для дальнейшего обработка данных, но это не попадание. В чем может быть проблема? что мне не хватает? пожалуйста помоги.


person Shreyas Pednekar    schedule 11.03.2019    source источник
comment
Я думаю, это потому, что вы явно устанавливаете OkResult и заканчиваете обработку, поскольку теперь он возвращает этот результат.   -  person Mark Fitzpatrick    schedule 11.03.2019
comment
Что мне там писать?   -  person Shreyas Pednekar    schedule 11.03.2019
comment
Вы пробовали просто дать ему провалиться? Если он не подтвержден, вы хотите, чтобы он возвращался неавторизованным, но если все в порядке, вы хотите, чтобы он просто продолжал работать.   -  person Mark Fitzpatrick    schedule 11.03.2019
comment
Я хочу продолжить это на своем api для дальнейшего доступа к данным, но он не попадает в api после проверки   -  person Shreyas Pednekar    schedule 11.03.2019
comment
Да, ты говоришь не делать этого. попробуйте закомментировать возвращаемый OkResult. Вы буквально тут же возвращаете результат действия. Вы справляетесь с отрицательным результатом, а это в первую очередь важно. Если проверка не удалась, вы хотите убить с неавторизованным результатом, что вы и делаете.   -  person Mark Fitzpatrick    schedule 11.03.2019
comment
Помимо простого возврата, вы также можете вернуть ChallengResult в случае, если в приложение заходит анонимный пользователь.   -  person MrKobayashi    schedule 11.03.2019


Ответы (1)


Вы не должны устанавливать filterContext.Result, если запрос успешно авторизован.

//
// Summary:
//     A context for authorization filters i.e. Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter
//     and Microsoft.AspNetCore.Mvc.Filters.IAsyncAuthorizationFilter implementations.
public class AuthorizationFilterContext : FilterContext
{
    //
    // Summary:
    //     Gets or sets the result of the request. Setting Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result
    //     to a non-null value inside an authorization filter will short-circuit the remainder
    //     of the filter pipeline.
    public virtual IActionResult Result { get; set; }
}

Вам нужно установить Result только в случае сбоя.

public class Authorization: AuthorizeAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext filterContext)
    {
        if (!ValidateToken(filterContext.HttpContext.Request.Headers["token"]))
        {
            filterContext.Result = new UnauthorizedResult();
        }
    }
}
person Edward    schedule 12.03.2019
comment
Я попробовал ваше решение, теперь оно дает мне код состояния 401 Неавторизовано даже после того, как фильтр успешно проверяет мой токен, в чем может быть проблема сейчас? - person Shreyas Pednekar; 12.03.2019
comment
Я попытался установить [AllowAnonymous] на моем контроллере GetMenu, теперь он попадает в GetMenu после проверки токена в фильтре аутентификации, но это правильный способ? - person Shreyas Pednekar; 12.03.2019
comment
@ShreyasPednekar Проверьте, верен ли ValidateToken(filterContext.HttpContext.Request.Headers["token"]). - person Edward; 12.03.2019
comment
Да, это правда - person Shreyas Pednekar; 12.03.2019
comment
@ShreyasPednekar Удалите [AllowAnonymous] и [Filters.Authorization], сработает ли метод? - person Edward; 12.03.2019
comment
Да, он попадает даже после удаления [AllowAnonymous], но показывает статус 401 Unauthorized - person Shreyas Pednekar; 12.03.2019
comment
@ShreyasPednekar Есть ли демо для воспроизведения вашей проблемы? - person Edward; 12.03.2019
comment
Да, если мы удалим [AllowAnonymous] из контроллера GetMenu, он воспроизведет эту проблему - person Shreyas Pednekar; 12.03.2019