Elenor Platz
Elenor Platz

Reputation: 87

ASP.NET Web API private controllers

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.

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.

Is that the best way to handle this scenario?

Thanks.

Upvotes: 6

Views: 3543

Answers (3)

Sagi
Sagi

Reputation: 1009

Use the Authorize Attribute:

[Authorize(Roles = "Admin")]
public  class MyPrivateDataController :ApiController

Upvotes: 0

drch
drch

Reputation: 3070

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.

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

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.

Upvotes: 8

CarlosB
CarlosB

Reputation: 91

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.

Upvotes: -1

Related Questions