Using IIS rewrite rules to rewrite from main website to sub application - asp.net

We have an ASP.NET Web API application (.NET 4.*) which is hosted as a website in IIS. The ASP.NET application contains server-side rendered pages, but also a REST API which is available at /api/v1.
A new API is in development, which is using ASP.NET Core (.NET 7) and will be hosted as an IIS application (believe me, we cannot get around that for now) under the main website (which contains the ASP.NET Web API application).
The new API should also be available on /api, but since this is an application under the main website, if we would use /api for the new application, the REST API of the main website would not receive requests anymore. Hosting it under /api/v2 is not possible as IIS applications cannot contain a / in the alias (and we also do not prefer a version in the path anymore).
Instead, we would like to create the application using another name, /foo for example, and use rewrite rules in the web.config to rewrite from the main website to the new application, eg.:
<system.webServer>
<rewrite>
<rules>
<rule name="Foo">
<match url="^api\/((?!v1).*)$" />
<action type="Rewrite" url="foo/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
But this doesn't seem to work. It looks like the request is rewritten, but still handled by the main website, not by the sub application. Is it not possible to rewrite (not redirect!) a request from a website to a sub application within that website? If not, any other suggestions to host both applications on the same starting path (it should remain two separate applications)? At the moment, there is no possibility for a reverse proxy which could solve this issue.

If you want to access requests starting with /api by typing /foo in the browser address bar, you can try the following rule:
<system.webServer>
<rewrite>
<rules>
<rule name="Foo">
<match url="foo(.*)" />
<action type="Rewrite" url="api{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>

Related

Removing Port number from a Blazor server side app in IIS

I have an intranet .NET Core Blazor server website running on a different port number of our website. I can access it perfectly fine using http://ourwebsite.com:8892 but I wanted to know if it can be rewritten to something like http://ourwebsite.com/blazorapp using IIS rewrite.
There is another application running on port 80 so I cannot use it.
This is something I wrote in the web.config file for the Blazor app
<rewrite>
<rules>
<rule name="removePort" stopProcessing="true">
<match url="^http://ourwebsite.com:8892(/.*)?$" />
<action type="Rewrite" url="http://ourwebsite.com/blazorapp{R:1}"/>
</rule>
</rules>
</rewrite>
I cannot get the rewrite to work. Whenever I go to ourwebsite.com/blazorapp, I hit the other application on port 80 and that shows 404 not found since the link I am looking for isn't on there. Is there something I am missing? Is url rewrite for a port number not possible for Blazor .NET core?
Any help would be appreciated.

Running asp.net and node.js as virtual applications in Azure

On Azure I have a Web App Service where I've been running and asp.net server for a long time. This server is used as a REST-api for a mobile application. Now i want to deploy a website, which is implemented as an React app. I discovered the ability to have virtual applications within a single Azure Web App which I believe is great.
I currently have two path set up with a virtual path, '/' leading to the asp.net server, and a virtual path '/web/' that leads to the react folder, as the image shows.
Virtual Path Setup
When i try to reach the react server from my browser, an asp.net error-page is showing up, which leads me to believe that asp.net handled my request rather than the react app. If i switch the virtual paths, the react app handles my request no matter the url i try to reach, blocking the asp.net server.
So the Web App is capable of hosting both asp.net servers and node.js servers, but i cannot get them to work side by side, handling requests on different paths.
I have also tried to add /web to the ignoreroutes of asp.net.
Perhaps there is some fundamentals i have missed, because i cannot find anyone with the same issues. I'm asking here because i was hoping someone had the same issues or has some clues. Thanks in advance.
Update
If anyone is in the same situation I have more findings in the issue. First of all, if i set the Managed Pipeline to Classic, rather than integegrated in the azure web app settings, Ii managed to reach the node.js application and the asp.net application as long as the root-path pointed to the asp.net app. However this broke some of my controllers in the asp app, and if i made the root path point to the node.js app, the node app still blocks the asp app like before.
My temporary workaround was to set the pipeline setting to Integrated, and separate the two applications into /api, and /web, where the default path '/' points to an empty directory
Solution
So its hard to say what was exactly wrong last time, but after cleaning up my Web.config files it managed to solve it.
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="React Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="server.js" />
</rule>
</rules>
</rewrite>
</system.webServer>
The rewrite rule is what is important here, if it matches the /api-pattern, the request is ignored by react and is let through to the asp server.

Disabling port 80 on an asp.net vnext website on azure

I have a feeling this should be easy, but I'm struggling to find out how to do it.
I have a website that I want to restrict to HTTPS. It is an asp.net vnext website (not mvc) that is deployed to Azure. It is serving up static files without going through the ASP.NET pipeline.
In previous versions of asp.net, you could add system.webServer rules to do a redirect. This is gone from vNext. If I was using Mvc I could use the RequireHttps attribute or I could write custom middleware to do the redirect, but this only kicks in when the asp.net pipeline is activated. My html and js (it's a SPA app) would still be served up. If I was deploying to IIS instead of Azure, I could configure it there.
So, how do I tell an azure website to only respond on port 443 without a web config file?
According to Azure Documentation you can add a web configuration file for applications written in any programming language supported by Azure (Node.js, PHP, Python Django, Java). You can find detailed information here.
Here is a sample:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Force HTTPS" enabled="true">
<match url="(.*)" ignoreCase="false" />
<conditions>
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
You can achieve the redirect by adding the web.config file to your deployment. The documentation says:
when hosted on Azure App Service- Azure creates the file automatically during deployment, so you never see it. If you include one as part of your application, it will override the one that Azure automatically generates.
for additional level of security probably you can use nsg. Azure documentation says NSG as "you can use Azure network security group to filter network traffic to and from Azure resources in an Azure virtual network".
You can try using cli to create a nsg and put rule in there to block traffic to port 80.

What is the correct way to be able to serve up an ASP.NET MVC page with URL /areas?

I am trying to get ASP.MVC to handle the URL /areas i.e. http://example.com/areas. By convention there is a folder called Areas, so /areas never gets to my controller.
I want to be able to tell MVC to ignore this folder in this one case.
Ordinarily I would not use a name that conflicts with an existing folder but I am migrating a web application from Django to ASP.NET MVC and have a section of pages under /areas. I would prefer not to have to change all the existing URL's just because of the framework.
For performance reasons I would prefer not to configure all requests to go through the MVC pipeline.
What other solutions are there?
It might be possible to use the IIS URL Rewrite module to redirect requests to specific folder and avoid the MVC pipeline completely.
The example below is from http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/ which shows how to rewrite paths to point at a static resource (Under the heading "Static content management.")
<rewrite>
<rules>
<rule name="Rewrite to new folder">
<match url="^Images/(.+)$" />
<action type="Rewrite" url="NewImages/{R:1}" />
</rule>
</rules>
</rewrite>
I'm curious if you could use an IgnoreRoute in your global.asax.cs file which would cause MVC to ignore that completely and not use the MVC processor for anything in that folder
routes.IgnoreRoute("areas/{*pathInfo}");

Multiple Country/Language Sites Under Single Web Application - TLD Routing Rewrites

I want to host multiple Top Level Domains (TLDs) off of the same web application.
Scenario: www.mywebsite.com has language sub-folders of /en-us/, /en-gb/, /fr-ca/, /ja/, etc...
So www.mywebsite.com/en-gb/ would be the UK version of the site.
UK users should go to www.mywebsite.co.uk but be routed to www.mywebsite.com/en-gb/
In IIS, I've set the bindings for this web application to handle both www.mywebsite.com and www.mywebsite.co.uk domains.
The URL Rewrite 2.0 module is added to IIS and includes this rule:
<rewrite>
<rules>
<rule name="CanonicalHostNameRule" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.mywebsite\.co\.uk$" />
</conditions>
<action type="Rewrite" url="http://www.mywebsite.com/en-gb/{R:1}" />
</rule>
</rules>
</rewrite>
Users who go to www.mywebsite.co.uk have the URL rewritten to www.mywebsite.com/en-gb/, however, I want the URL to remain www.mywebsite.co.uk for them, and in fact, I would want the www.mywebsite.com/en-gb/ to be rewritten to www.mywebsite.co.uk for consistency.
I'm still not even quite sure what the proper terminology is for what I want to do. So far I've run across 'multi-tenancy', 'application request routing', 'URL routing', 'URL rewriting', and a few others.
Here are a few resources I've been reading to try and figure out how best to handle this. Am I on the right track? I haven't found a good example that demonstrates doing this with TLD's.
Scott Forsyth - Multiple Domains Under One Site
Scott Guthrie - URL Routing With ASP.NET 4 Webforms
Stackoverflow - MVC Routes Based On A SubDomain

Resources