【问题标题】:How can I disable some APIs of my ASP.NET application如何禁用我的 ASP.NET 应用程序的某些 API
【发布时间】:2016-12-23 19:33:03
【问题描述】:

假设我有一个包含一些 API 的 ASP.NET 应用程序。

例如,

{HostName}/api/a/*      
{HostName}/api/b/*

现在我想禁用所有{HostName}/api/a/* API(但保留/api/b/*)。当客户端调用/api/a/* API 时,会收到 404 错误。客户端调用/api/b/*接口时,正常响应。

有没有办法在 c# ASP.NET 应用程序中做到这一点?

【问题讨论】:

  • 在代码中删除它们?
  • 您可以实现DisableFunctionalityActionFilter 之类的东西并将其分配给必须禁用的控制器/区域/操作。
  • 只需将控制器名称更改为无意义的名称。
  • 您在寻找NonAction 属性吗? 要防止方法作为操作被调用,请使用 NonAction 属性。这向框架表明该方法不是一个动作,即使它会匹配路由规则。
  • 由于我要禁用的 API 太多,并且禁用操作可能只是暂时的(可能有一天会重新启用),因此在代码中删除它们或为每个函数添加一个属性似乎太多了工作要做...

标签: c# asp.net api


【解决方案1】:

可以采取多种方法来禁用 cmets 中提到的某些操作或路由。

1.) [NonAction] 属性

System.Web.Http 中的 [NonAction] 属性可应用于 ApiController 操作。如果调用了这样的方法,则服务器返回 HTTP 代码 404(未找到方法)。该属性只能应用于方法级别,而不能应用于类。所以每一个方法都必须用这个属性装饰。

2.) 编写自定义操作过滤器

这种方法为您提供了更多控制权。您的过滤器可以应用于类级别,并且您可以实现一些更高级的逻辑,在这些条件下您的控制器是否可以访问(取决于日期、许可证、功能切换等)

public class MyNoActionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {            
        if (IfDisabledLogic(actionContext))
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.NotFound);
        }
        else                
          base.OnActionExecuting(actionContext);
    }
}

[MyNoActionFilter]
public class ValuesController : ApiController
{
    // web api controller logic...
}

3.) WebApiConfig.cs中的路由配置

您可以在 WebApiConfig 中为无法访问的控制器添加 Web api 路由,并将此路由映射到不存在的控制器。然后框架走这条路线,没有找到控制器并向客户端发送404返回码。将这些路由放在开头很重要,以避免意外执行。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        
        config.Routes.MapHttpRoute(
            name: "DisabledApi",
            routeTemplate: "api/b/{id}",
            defaults: new { controller = "DoesNotExist", id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

因为您声明由于工作量大而不要使用属性,所以我推荐第三个选项,因为路由配置为此定义了一个地方。如果您想在将来再次启用该路由,您只需删除一个路由定义。

【讨论】:

  • 对于 Net Core 中的方法 2,而不是设置 actionContext.Response 您应该设置 actionContext.Result 以便它立即返回;即:actionContext.Result = new NotFoundObjectResult(actionContext.ModelState);
【解决方案2】:

可能是一个 hack,但对我来说很好:

将控制器的范围从 public 更改为 internal 会隐藏该控制器类的所有操作。所以:

internal class AController : ApiController
{
  [...]
}

对 http://host/api/a/* 的请求将失败 "没有找到与名为 'a' 的控制器匹配的类型。"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2021-06-25
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    相关资源
    最近更新 更多