Web API 2的自定义异步操作筛选器

时间:2017-01-13 12:09:52

标签: asp.net-web-api methods async-await custom-action-filter filterattribute

我有一个web api来使用来自android mobile的数据。此Web api将使用多部分文件以及web api请求的表单数据。我跟着this文章进行了归档。

[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)中正常工作,允许对方法的请求。

Postman Response screen shot

这不适用于移动应用,将响应消息称为未经授权的访问。并且即使自定义访问验证被传递,也不允许对该方法的请求。

仅供参考:此方法在没有过滤器的移动设备中正常工作

帮助我在移动应用中也可以使用它。

提前致谢。

1 个答案:

答案 0 :(得分:0)

您使用错误类型的过滤器来管理访问权限。您应该使用授权过滤器。此外,您无法使用异步方法进行授权。你必须让呼叫客户端等待清除。这可能会导致您遇到的副作用。

我不确定这是否与移动应用程序有关,但在处理请求之前是授权阶段。确认您的项目中未使用任何其他形式的授权。

您应该通过继承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.
        }
    }
}

您可以使用此属性来装饰您的控制器。您甚至可以在构造函数中传递参数,以便对访问管理进行更精细的控制,例如访问控制器所需的角色。