Web Api授权过滤器

时间:2014-08-27 18:56:50

标签: .net c#-4.0 autofac asp.net-web-api2

我有一个web api授权过滤器,应用于web api控制器的基本控制器。授权类型为Basic。授权过滤器使用IAutofacAuthenticationFilter,并使用一些autofac注入服务来执行授权和身份验证。

在GET请求中,一切都按预期工作。 读取并确认授权标头,并且如果请求在授权标头中没有正确的授权信息,则响应使用请求。

public void OnChallenge(HttpAuthenticationChallengeContext context) {
    var host = context.Request.RequestUri.DnsSafeHost;
    context.Request.CreateResponse(HttpStatusCode.Unauthorized, "Unauthenticated request");
    context.Request.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", host));
}

然而,当发出POST请求时,所有内容都以相同的方式调用,并且上述方法按预期调用,但请求通过转到实际的控制器操作继续处理。

OnAuthorization未被修改或重载。取而代之的是,

OnAuthenticate看起来像这样:

public void OnAuthenticate(HttpAuthenticationContext context)
    {


        var identity = ParseAuthorizationHeader(context.ActionContext); // identity is a custom object representing the information in the auth header
        if (identity == null) {
            HandleUnauthorizedRequest(context.ActionContext);
            return;
        }


        if (!OnAuthorizeUser(identity.Name, identity.Key, context.ActionContext)) {
            HandleUnauthorizedRequest(context.ActionContext);
            return;
        }
    }

以下是设置主体并对用户进行身份验证的自定义方法:

protected virtual bool OnAuthorizeUser(KeyContainer name, string key, HttpActionContext actionContext) {

        // get principal code ...

        Thread.CurrentPrincipal = principal;
        actionContext.RequestContext.Principal = principal;
        if (HttpContext.Current != null)
            HttpContext.Current.User = principal;

        return true;
    }

使用以下内容向容器注册授权过滤器:

builder.Register(c =>
           new AuthorizeActionFilterAttribute(
               c.Resolve<IService>())
           .AsWebApiAuthenticationFilterFor<BaseApiController>()
           .InstancePerRequest();

POST请求中发生的与GET不同的是什么?如何解决?

1 个答案:

答案 0 :(得分:2)

我猜测问题在于过滤器的InstancePerRequest注册。我们有一个fairly extensive FAQ on per-request scope usage,其中一部分注意到you can't have per-request dependencies in filters因为WebAPI在创建控制器后会为控制器缓存过滤器实例 - 成功完成工作的唯一方法(如您所发现的)是使用过滤器本身内的服务位置。不幸的是,从Autofac方面我们无能为力;它在WebAPI中都是内置且不可覆盖的,以此方式行事。

希望他们能在ASP.NET vNext中更改它。

相关问题