ASP.NET Web API私有控制器

时间:2022-07-27 03:21:07

I have an ASP.NET Web API project with two controllers, one of which I want to be publicly addressable over the internet and the other which I only want to be called internally over the network.

我有一个带有两个控制器的ASP.NET Web API项目,其中一个我想通过互联网公开寻址,另一个我只想通过网络内部调用。

The best solution that I can come up with so far is to have a route template for public controllers and a template for internal: -

到目前为止,我能提出的最佳解决方案是为公共控制器提供路由模板,为内部提供模板: -

routeTemplate: "api/{controller}/{id}"

routeTemplate: "privateapi/{controller}/{id}"

That way I can configure IIS to block requests to the ‘privateapi’ route.

这样我就可以配置IIS来阻止对'privateapi'路由的请求。

Is that the best way to handle this scenario?

这是处理这种情况的最佳方式吗?

Thanks.

2 个解决方案

#1


7  

The problem with controlling access MVC and WebAPI in IIS is that routing can sometimes make it difficult to see exactly which routes are ending up at your controller. It is perfectly valid (and in many cases preferred) to restrict access in the code as well.

在IIS中控制访问MVC和WebAPI的问题在于,路由有时会使您很难确切地看到哪些路由最终会出现在您的控制器上。在代码中限制访问也是完全有效的(并且在许多情况下是优选的)。

To do this in code, you can do something like the following which uses a custom AuthorizeAttribute to filter out unauthorized users.

要在代码中执行此操作,您可以执行类似以下操作,使用自定义AuthorizeAttribute来过滤未经授权的用户。

public class InternalAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.Request.Properties.ContainsKey("MS_HttpContext"))
        {
            var ipAddress =
                ((HttpContextWrapper) actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
            if (IsPrivateAddress(ipAddress))
            {
                return;
            }
        }

        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Forbidden");
    }

    private bool IsPrivateAddress(string ipAddress)
    {
        // todo: verify ip address is in internal or otherwise whitelisted
    }
}

You can then annotate your controller and have the filter applied on all actions in your controller.

然后,您可以注释控制器并将过滤器应用于控制器中的所有操作。

[InternalAuthorize]
public class PrivateController : ApiController
{
}

Note: if the information/actions from this controller is particularly sensitive, you may want to deploy a version of your application that exposes this private api and blocks all traffic non from your whitelist rather than relying on application logic to keep bad guys out.

注意:如果来自此控制器的信息/操作特别敏感,您可能希望部署应用程序的一个版本,该应用程序公开此私有API并阻止来自白名单的所有流量,而不是依赖应用程序逻辑来阻止坏人。

#2


-1  

You can't do this! What you are doing is just creating another route for your controllers.

你不能这样做!你正在做的只是为你的控制器创建另一条路线。

If they are deployed online they are accessible. Now what you need is to deploy 2 different API's one at an external machine and another at an internal machine.

如果他们在线部署,则可以访问。现在您需要的是在外部机器上部署2个不同的API,在内部机器上部署另一个API。

#1


7  

The problem with controlling access MVC and WebAPI in IIS is that routing can sometimes make it difficult to see exactly which routes are ending up at your controller. It is perfectly valid (and in many cases preferred) to restrict access in the code as well.

在IIS中控制访问MVC和WebAPI的问题在于,路由有时会使您很难确切地看到哪些路由最终会出现在您的控制器上。在代码中限制访问也是完全有效的(并且在许多情况下是优选的)。

To do this in code, you can do something like the following which uses a custom AuthorizeAttribute to filter out unauthorized users.

要在代码中执行此操作,您可以执行类似以下操作,使用自定义AuthorizeAttribute来过滤未经授权的用户。

public class InternalAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext.Request.Properties.ContainsKey("MS_HttpContext"))
        {
            var ipAddress =
                ((HttpContextWrapper) actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
            if (IsPrivateAddress(ipAddress))
            {
                return;
            }
        }

        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Forbidden");
    }

    private bool IsPrivateAddress(string ipAddress)
    {
        // todo: verify ip address is in internal or otherwise whitelisted
    }
}

You can then annotate your controller and have the filter applied on all actions in your controller.

然后,您可以注释控制器并将过滤器应用于控制器中的所有操作。

[InternalAuthorize]
public class PrivateController : ApiController
{
}

Note: if the information/actions from this controller is particularly sensitive, you may want to deploy a version of your application that exposes this private api and blocks all traffic non from your whitelist rather than relying on application logic to keep bad guys out.

注意:如果来自此控制器的信息/操作特别敏感,您可能希望部署应用程序的一个版本,该应用程序公开此私有API并阻止来自白名单的所有流量,而不是依赖应用程序逻辑来阻止坏人。

#2


-1  

You can't do this! What you are doing is just creating another route for your controllers.

你不能这样做!你正在做的只是为你的控制器创建另一条路线。

If they are deployed online they are accessible. Now what you need is to deploy 2 different API's one at an external machine and another at an internal machine.

如果他们在线部署,则可以访问。现在您需要的是在外部机器上部署2个不同的API,在内部机器上部署另一个API。