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

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.

Related

Using IIS rewrite rules to rewrite from main website to sub application

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>

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.

How to host an ASP.NET Web API that is composed of multiple projects in IIS?

I am new to ASP.NET Web API and to RESTful services in general. I recently started working in a Web API that was already started by another developer that is no longer in the company, and the approach that he used for making this API was to create a new project for every Resource that the API exposes. My question is, what is the correct way to host this API in IIS? I can create a new Website in IIS manager for each project, but then I will have many sites. Also, for testing purposes I tried creating just one Website in IIS and then adding an Application within the Web Site for each service that have to be deployed, and this also works, the problem is that for each project (resource) a virtual directory is created and then the route to access the Resource includes the virtual directory name and I don’t want this, because then the routes will look like this:
BaseURL/VirtualDirectory /api/resource
I have googled for examples on how to host an ASP.NET Web API in IIS, but all the posts that I have found show how to host a single service project, and not an API that is composed of multiple projects. So, I would really appreciate if someone could point me in the right direction. Thanks in advance.
According to your description , I guess you want the url should now show the vitual directory.
E.g:
VirtualDirectoryName.yourdomain.com/api/resource to www.yourdomain.com/VirtualDirectory/api/resource.
If this is your requirement, I suggest you could try to use url rewrite extension to achieve your reuqirement.
You could dirctly download it from below url:
https://www.iis.net/downloads/microsoft/url-rewrite
Then you could use below rewrtite rule into the web.config.
<rule name="Test" stopProcessing="true">
<match url="(.*)" ignoreCase="true" />
<conditions>
<add input="{HTTP_HOST}" pattern="(.+).sample1.com" />
</conditions>
<action type="Rewrite" url="http://www.sample1.com/{C:1}" />
</rule>

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.

"This webpage is not available" from localhost after SSL removed

When I attempt to debug my ASP.NET MVC 5 project I am getting the IIS error "This webpage is not available". Here is the sequence of events that led to this:
The project was originally using SSL and IIS Express and working fine.
I wanted to use Fiddler and saw that Fiddler doesn't (easily) monitor https traffic, so went into the project properties (F4) tab and changed it back to use http.
This is when I started seeing the error "The page can't be displayed". I noticed that even though my ProjectUrl and Start URL in the project properties window was http://localhost:57505, when I debugged, the URL would change to https.
A complication (sorry, I don't remember what it was) prompted me to use Local IIS (IIS 7.5) instead of IIS Express.
I restarted IIS and I decided to get rid of the SSL certificate in IIS but that didn't help.
Because nothing worked I changed the project back to use SSL. Now I am seeing "This webpage is not available" when I debug.
I have rebooted and recycled frequently
I'm not sure what to do next because my project is unusable right now. Any help appreciated.
Did you happen to had an entry in web.config that force a redirection to the HTTPS site?
<rewrite>
<rules>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="^account/logon$|^account/register$" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
Note that redirectType="Permanent", it will return Permanent Redirect(301) to your browser. This will be cached permanently on your browser so you couldn't access the normal HTTP site even if you've removed this redirection. You will need to manually clear your browser caches to fix it.
If it happens with other projects as well then try to disable windows firewall or any other firewalls on the system and hopefully it should work.
Also try to run the website without fiddler and see if it works.
I had similar problem and it was the firewall causing it.
With HTTPS, you can only have one "web site" per ip_address:port. So https://localhost, https://example.com, it's all the same (modulo certificate errors.)
HTTP, however, allows multiple web sites per ip_address:port pair, via the "HOST" header in the HTTP 1.1 spec. IIS needs to know what site you want, and it defaults to binding the web site to the machine's hostname. (That is probably what is getting you.)
If you just want all requests that resolve to your host (like "localhost") to hit the same web site, edit the site bindings in inetmgr and set "Host Name" to empty string or *.

Resources