我有一个带有两个控制器的 ASP.NET Web API 项目,其中一个我想通过 Internet 公开寻址,另一个我只想通过网络在内部调用。
到目前为止,我能想到的最好的解决方案是为公共控制器提供一个路由模板和一个用于内部的模板:-
路由模板:“api/{controller}/{id}”
routeTemplate: "privateapi/{controller}/{id}"
这样我就可以将 IIS 配置为阻止对“privateapi”路由的请求。
这是处理这种情况的最佳方法吗?
谢谢。
我有一个带有两个控制器的 ASP.NET Web API 项目,其中一个我想通过 Internet 公开寻址,另一个我只想通过网络在内部调用。
到目前为止,我能想到的最好的解决方案是为公共控制器提供一个路由模板和一个用于内部的模板:-
路由模板:“api/{controller}/{id}”
routeTemplate: "privateapi/{controller}/{id}"
这样我就可以将 IIS 配置为阻止对“privateapi”路由的请求。
这是处理这种情况的最佳方法吗?
谢谢。
在 IIS 中控制访问 MVC 和 WebAPI 的问题在于,路由有时会让人很难准确地看到哪些路由最终到达您的控制器。限制代码中的访问也是完全有效的(并且在许多情况下是首选)。
要在代码中执行此操作,您可以执行以下操作,使用自定义 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
}
}
然后,您可以注释控制器并将过滤器应用于控制器中的所有操作。
[InternalAuthorize]
public class PrivateController : ApiController
{
}
注意:如果来自此控制器的信息/操作特别敏感,您可能希望部署一个公开此私有 api 并阻止所有非白名单中的流量的应用程序版本,而不是依靠应用程序逻辑来阻止坏人。
使用授权属性:
[Authorize(Roles = "Admin")]
public class MyPrivateDataController :ApiController
你不能这样做!您所做的只是为您的控制器创建另一条路线。
如果它们在线部署,它们是可访问的。现在您需要在外部机器上部署 2 个不同的 API,在内部机器上部署另一个。