How to allow internal MVC Web Api from external site outside the network

I have a MVC Web API (hosted in IIS) which is in the wwwroot folder and locally accessible within the network.I can execute api calls like this: http://mylocalapi:133/api/Values/Get and I get a result.

I have an external site which is http://example.org and I would like to execute the same http://mylocalapi:133/api/Values/Get.

Both the external facing site as well as the internal API site is hosted on the same server (but it can be different, for example a 3rd party vendor outside of the network)

I have CORS set up in my API like this:

[EnableCors(origins: "http://example.org", headers: "*", methods: "*")]

But I keep getting the following error:

XMLHttpRequest cannot load http://mylocalapi:133. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.org' is therefore not allowed access.

So get around it, I created a virtual directory (APICALLS) in my external site and created a web.config file which will point to the local IIS site:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpRedirect enabled="true" destination="http://mylocalapi:133" exactDestination="true" />
    </system.webServer>
</configuration>

When I do that, I try to access the API like this: http://example.org/APICALLS/api/Values/Get but I get the following error:

XMLHttpRequest cannot load http://mylocalapi:133. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.org' is therefore not allowed access.

What am I doing wrong and how can I resolve the issue.


Solution 1:

You cannot access an internal-only site from JavaScript, as JavaScript runs client-side, on the end-user's machine, outside of your internal network. The only way to hit the API via JavaScript is to either 1) expose the API to the external network or 2) create a proxy within your external site.

The proxy would be basically an action or actions that offer external access, and then translate the calls to your internal API. At the simplest, you could have a single action that basically responds to something like:

https://foo.com/api?endpoint=/internal/api/endpoint/&someParam=foo

The action would then take this information in the query string and use that to make a request to your internal API via something like HttpClient. However, this approach pretty much exposes your whole internal API, so you might as well just move it outside at that point. The better approach would be to create specific endpoints (action methods) for specific internal API calls you need to make via JavaScript.

UPDATE

It's difficult to give you any real direction here without context. Let's say that there's an internal API endpoint that returns a list of widgets and you want to retrieve this list of widgets via AJAX. You would need something like:

public async Task<ActionResult> GetWidgets()
{
    // fetch widgets from internal API via HttpClient
    return Json(widgets, JsonRequestBehavior.AllowGet);
}

Then, your AJAX would call the URL for this action method on your website, which under the hood calls the internal API.