在Web API中正确实现IAuthorizationFilter

Dyl*_*ley 20 asp.net-web-api

我在使用System.Web.Http.Filters中的IAuthorizationFilter来解决如何在Web API中实现授权过滤器时遇到了麻烦.

这是一个简单的过滤器,我写的是为了响应所有带有403禁止响应的非https请求:

public class HttpsFilter : IAuthorizationFilter {
    public bool AllowMultiple {
        get {
            return false;
        }
    }

    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync( HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation ) {
        var request = actionContext.Request;

        if ( request.RequestUri.Scheme != Uri.UriSchemeHttps ) {
            HttpResponseMessage response = request.CreateResponse( HttpStatusCode.Forbidden );
            response.Content = new StringContent( "<h1>HTTPS Required</h1>", Encoding.UTF8, "text/html" );
            actionContext.Response = response;

            return new Task<HttpResponseMessage>( delegate() {
                return response;
            } );
        }
        else
            return continuation();
    }
}
Run Code Online (Sandbox Code Playgroud)

我到目前为止所写的内容已经运行,但是当我尝试通过常规http访问api时,它只是挂起而且我从来没有得到过响应.

Kir*_*lla 8

对于您的场景,您可以简单地从"System.Web.Http.AuthorizeAttribute"派生.

例:

public class HttpsFilterAttribute : System.Web.Http.AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您有理由想要使用接口而不是`AuthorizeAttribute`.`AuthorizeAttribute`很好,因为它为你处理了很多东西,并公开了一些方便的方法,使这个过程更容易,但它也将属性与过滤器结合在一起.这使得无法将依赖项注入到过滤器构造函数中.此外,您的过滤器不能使用泛型.通过拆分过滤器和属性的关注点来解决所有这些问题.当然,这一切都假设您的过滤器旨在补充或完全不相关,而不是补充AuthorizeAttribute. (7认同)
  • 基兰是对的.从AuthorizeAttribute派生 - 除了自定义authZ逻辑(例如支持AllowAnonymous)之外,还有更多内容.如果您想了解其内部工作原理,请使用反射器. (2认同)

Dmi*_* S. 6

您需要将任务保存到变量中并task.Start()在返回之前调用该方法,或者使用该Task<HttpResponseMessage>.Factory.StartNew(Action action)方法创建任务。

  • 在这种(准异步)情况下,如何`return Task.FromResult&lt;HttpResponseMessage&gt;(response);` (17认同)