6

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.

3 Answers 3

8

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.

Sign up to request clarification or add additional context in comments.

Comments

0

Use the Authorize Attribute:

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

Comments

-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.

1 Comment

CarlosB is right, this is a security/firewall solution not a code solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.