0

我有一个 web api 来使用来自 android mobile 的数据。这个 web api 将使用 web 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);
    }

我想为这个 web 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 客户端工具(例如:邮递员)中运行良好,允许对该方法的请求。

邮递员响应屏幕截图

这在移动应用程序中不起作用,将响应消息说为未经授权的访问。即使通过了自定义访问验证,也不允许对该方法的请求。

仅供参考:此方法在没有过滤器的移动设备中运行良好

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

提前致谢。

4

1 回答 1

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.
        }
    }
}

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

于 2017-01-27T17:35:32.227 回答