【问题标题】:Bypassing global message handlers for specific routes绕过特定路由的全局消息处理程序
【发布时间】:2017-11-15 22:28:21
【问题描述】:

我正在开发一个 Web 服务,它的 API 都需要身份验证。使用WebApiConfig 中配置的全局消息处理程序执行身份验证,如下所示:

config.MessageHandlers.Add(new AuthMessageHandler());

现在我们想公开一个不执行身份验证的新 API。我最初的方法是为这个新 API 配置每个路由处理程序,但是从我在各个地方(例如Microsoft docs about HTTP message handlers)读到的内容来看,全局消息处理程序在HttpRoutingDispatcher 之前被调用,所以请求仍然会通过在访问任何每个路由处理程序之前通过全局处理程序。我想出了一些可能的解决方案:

  1. 为所有路由配置每个路由的处理程序。我们有非常多的 API,但由于代码的编写方式,我认为这可能只是一行添加和删除。不过我不喜欢它,因为我们必须在以后添加新路由时更加小心,以确保它们得到正确的身份验证。另外,由于我们支持的 API 数量之多,我不相信我一定能涵盖所有这些。我们在全球范围内这样做是有原因的。

  2. 修改处理程序,为绕过身份验证的路由设置某种白名单。我想避免这种情况,因为它会使处理程序代码复杂化。此外,它位于一个完全不同的通用代码库中,我真的不想在那里挖掘......

您可能会说,如果可能,我想避免使用这两种解决方案。有没有办法从全局消息处理程序中排除某些路由?也许这会破坏首先拥有一个全局处理程序的目的,但如果这能以某种方式成为可能,那就太好了。

【问题讨论】:

  • 或者在这些控制器上使用AllowAnonymous 属性让身份验证处理程序知道放弃身份验证。如果有问题的处理程序无法识别此类属性,则应对其进行更新以这样做。这就是属性的用途。

标签: c# asp.net-web-api asp.net-web-api-routing


【解决方案1】:

正如对原始问题的评论所建议的那样,解决方案是在具有匿名 API 的控制器上使用 AllowAnonymousAttribute。仅此一项并不能解决问题,因为我们不使用构建 AllowAnonymousAttributeAuthorizeAttribute,但我们的处理程序可以使用此检查来确定是否授权请求:

    private bool AllowAnonymousAccess(HttpRequestMessage request)
    {
        IHttpControllerSelector selector = GlobalConfiguration.Configuration.Services.GetHttpControllerSelector();
        HttpControllerDescriptor descriptor = selector.SelectController(request);
        Type controllerType = descriptor.ControllerType;
        return controllerType.GetCustomAttribute<AllowAnonymousAttribute>(true) != null;
    }

请注意,这只适用于控制器级别。我无法找到一个快速的解决方案来确定将调用哪个控制器方法以及该方法是否具有该属性,因为在请求链的这一点上这显然不是那么容易做到的。

【讨论】:

  • 这拯救了我的一天 :)
猜你喜欢
  • 2014-12-26
  • 2012-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
相关资源
最近更新 更多