【问题标题】:WebApi Authorization FilterWebApi 授权过滤器
【发布时间】:2014-08-27 18:56:49
【问题描述】:

我有一个 web api 授权过滤器,它应用于 web api 控制器的基本控制器。授权类型为基本。授权过滤器使用 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();

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

【问题讨论】:

  • OnAuthenticate 方法中你在做什么?
  • @PeterLillevold 我用更多信息更新了这个问题。有趣的是,如果我不使用 Autofac 的 IAutofacAuthenticationFilter 接口并使用 var dependecyScope = actionContext.Request.GetDependencyScope();var lifetimeScope = dependecyScope.GetRequestLifetimeScope();_service = lifetimeScope.Resolve&lt;IService&gt;() 解决我需要的服务并使用过滤器装饰 Base api 控制器,问题就会消失。

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


【解决方案1】:

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

希望他们会在 ASP.NET vNext 中改变这一点。

【讨论】:

  • 缓存不会影响 GET 和 POST 请求吗?该问题仅发生在发布请求上。我会查看常见问题解答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 2016-10-27
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 2019-09-12
相关资源
最近更新 更多