Настраиваемый фильтр асинхронных действий для Web API 2

У меня есть веб-api, чтобы потреблять данные, поступающие с android mobile. Этот веб-api будет использовать файл нескольких частей вместе с данными формы запроса веб-api. Я последовал за этой статьей в архив.

[CustAuthAsync]
public async Task<HttpResponseMessage> SaveEHSInspectionData()
    {          
        try
        {             
            string root = HttpContext.Current.Server.MapPath("~/App_Data");
            MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(root); 
           //do stuff
           var res = await Request.Content.ReadAsMultipartAsync(provider);
           // DO SOME STUFF
        }
        catch (Exception exp)
        {

        }
        return Request.CreateResponse(HttpStatusCode.OK, result);
    }

Я хотел сделать пользовательскую проверку доступа для этого веб-api, поэтому реализовал фильтр для проверки запроса.

У меня есть фильтр, как показано ниже

public class CustAuthAsyncAttribute : ActionFilterAttribute
{
    public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {            
        InternalOnExecutingAsync(actionContext);
    }
}

Внутренний метод, как это

protected void InternalOnExecutingAsync(HttpActionContext actionContext)
        {
            var authValue = actionContext.Request.Headers;

if (authValue.Contains("CustomAccessToken"))
            {                
                string token = authValue.GetValues("CustomAccessToken").First();

                var result = // doing some decription

                if (result != null)
                {                    
                    bool validationResult = // validation with database
                    if (!validationResult)
                    {                        
                        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
                        { ReasonPhrase = "Invalid token" };
                    }                    
                }
                else
                {
                    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
                    { ReasonPhrase = "Invalid token" };
                }
            }
            else
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized)
                { ReasonPhrase = "Unauthorized Request" };                
            }

Эти реализации прекрасно работают в клиентских инструментах API (например: Postman), если проверка проходит, разрешает запрос к методу.

Ответ почтальона снимок экрана

Это не работает в мобильном приложении, говоря ответное сообщение как несанкционированный доступ. и не позволяя запрос к методу даже пользовательские проверки доступа передаются.

FYI: этот метод отлично работает в мобильном телефоне без фильтра

Помогите мне получить это работает в мобильном приложении также.

Спасибо заранее.

1 ответ

  1. Использование неправильного типа фильтра для управления доступом. Следует использовать фильтр авторизации. Кроме того, вы не можете иметь асинхронный метод для авторизации. Вы должны заставить вызывающего клиента ждать разрешения. Это может вызвать побочные эффекты, которые вы испытываете.

    Я не уверен, что это связано с тем, что это мобильное приложение, однако этап авторизации ir до обработки запроса. Убедитесь, что вы не используете в проекте никакой другой формы авторизации.

    Следует реализовать фильтр авторизации путем наследования AuthorizeAttributeи переопределения IsAuthorized(HttpActionContext actionContext)метода:

    public class CustAuthAsync : AuthorizeAttribute
    {
        public CustAuthAsync()
        {
            ///Some initialization if required. Otherwise, not necessary to declare the constructor..
        }
    
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            var authValue = actionContext.Request.Headers;
    
            if (authValue.Contains("CustomAccessToken"))
            {
                string token = authValue.GetValues("CustomAccessToken").First();
    
                var result = // doing some decription
    
                if (result != null)
                {
                    return //database validation
                }
                else
                {
                    return false;
                    //No need to create special unauthorized response. You should not hint the reason at this point. You can do this in the HandleUnauthorizedRequest method.
                }
            }
            else
            {
                return false;//No need to create special unauthorized response.
            }
        }
    }
    

    Этот атрибут можно использовать для украшения контроллеров. Вы даже можете передать параметр в конструкторе для более детального управления по управлению доступом, как требуемая роль для доступа к контроллеру de.