IIS Rewrite / Application Request Routing (ARR) Half-working - iis

I have several rules in my rewrite, including ARR that have been working for over a year, now it's almost like the top rules in the web.config file are no longer being called in the correct order.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="AuthRoute" stopProcessing="true">
<match url="(auth$|auth/(.*))" />
<action type="Rewrite" url="http://localhost:8083/auth/{R:2}" />
</rule>
...
<rule name="Non-File Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
As you can see, I have a separate route for /auth that reverse-proxies to a different application designed for everything in /auth ... In this case, there are several files foo.HASH.css and foo.HASH.js that are actually there, the backend application is serving them, but the front end is getting the parent application (via IIS) of the /index.html.
Some files are being reverse proxied correctly, others simply are not. It's weird, I'm not sure if it's a windows/iis update that started this or what.

Turns out the content for the app being reverse proxied wasn't being published with the path prefix. Since browsers aren't showing the full path in the list, the aren't too load from root was missed.

Related

IIS Rewrite Module and sub applications / React-Router

Ok, this is similar to other questions out there but I am not familiar with url rewrite.
I am hosting (hopefully only for development and testing) a react application under IIS.
If hosted in the root of the site folder all is well using
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Static Assets" stopProcessing="true">
<match url="([\S]+[.](svg|js|css|png|gif|jpg|jpeg))" />
<action type="Rewrite" url="{R:1}" />
</rule>
<rule name="ReactRouter Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
But I need it to work in a subapplication. For instance: http://myserver:8888/myapp. Where myapp is the sub application.
IIS diagram:
Sites
- MySite
- MyApp
Better example of the url that includes the route: http://myserver:8888/myapp/1234/abcd.
1234 and abcd are route values/params.
contents of my app directory are:
index.html
main.a9e1df0325f4fdb57e7e.js
vendors~main.c8848853e10f698af19d.js
web.config
Thanks
Gina
You could host your app in any subapplication in iis but be careful to defining correct route for serving contents. It seems you want to host static content so you can't use route parameters in url hence these parameters are used by asp.net. Static content are served by iis. You can try this url for serving content in myapp:
http://myserver:8888/myapp/index.html

How to redirect a specific sub-domain to a main domain using in IIS using web.config?

Currently I have a sub-domain https://blog.example.com which I would like to redirect to https://example.com/blog. I'm using Craft CMS running on IIS 7 server.
I tried the code mentioned below but it didn't work:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect blog to new url" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern=".*" />
</conditions>
<action type="Redirect" url="https://example.com/blog/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Update: Adding directory structure
The problem seems to be with the condition you have specified. Your current pattern is .* which will result in a infinite loop. Change the pattern to check for the specific URL as below.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect blog to new url" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern=".*blog\.example\.com.*" />
</conditions>
<action type="Redirect" url="https://example.com/blog/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I tried this and it works for me. Go to http://blog.kaushal.co.in
If you need to troubleshoot URL Rewrite rules, then enable Failed Request tracing for your site. See this for more details: Using Failed Request Tracing to Trace Rewrite Rules
UPDATE
The rewrite rules need to be added to the 117072616095252 present at the site's root "/" and not in a web.config of one of the child folders.

Azure web app redirect http to https

I use Azure cloud with web app and my server side written on nodejs.
When web app receive a http request I want to redirect the request to https
I found the solution.
I put that to my web.config file inside the rules tag
<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="false" redirectType="Permanent" />
</rule>
The problem is when I type in the browser "https://myURL.com" it redirect to main screen every thing ok,
but when I change https to http "http://myURL.com" it redirect to https://myURL.com/" and add to the url "bin/www" according that the url looks like that "http://myURL.com/bin/www", the response is: page doesn't find.
The question is how to redirect a clear url without added data to the url?
Part of my web.config file:
<rewrite>
<rules>
<!-- Do not interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^bin/www\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="bin/www" />
</rule>
<!-- Redirect all traffic to SSL -->
<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="false" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
<!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin" />
</hiddenSegments>
</requestFiltering>
</security>
Thanks for answers, Michael.
Go to Azure portal and open the overview page of the (Web) App Service you wanna set to HTTPS only. In the sidebar, under the Settings section, there is an option for TLS/SSL Settings.
On clicking it, you will get an option on the screen to set your app's protocol to HTTPS only. There isn't any need to manually add separate ruleset for this.
This works on every tier of App Service Plan including the 'F'-Series (free subscription).
Note that, if you are adding any custom domain you also need to add corresponding SSL bindings, you can easily get them using LetsEncrypt or alike. If any of the custom hostnames for your app are missing SSL bindings, then:
When HTTPS Only is enabled clients accessing your app on those custom hostnames will see security warnings.
PS: I just saw that this question was asked about 3 years ago and that time maybe there was no direct option to do this. But even so, I'm posting my answer because on Google (as on February 2020) this question still ranks first among others regd. automatic HTTPS redirection in Azure.
As of November 2017, this is now a simple switch in the Azure Portal: "HTTPS Only", under Custom domains.
https://blogs.msdn.microsoft.com/benjaminperkins/2017/11/30/how-to-make-an-azure-app-service-https-only/
It's also very easy in ARM:
“httpsOnly”: true
There is also a free and open source extension for this.
Go to your Web App settings sidebar, search for the "Extensions" tab and click on "Add".
Scroll down and find the extension Redirect HTTP to HTTPS by gregjhogan.
Accept the terms.
Restart the Web App for the actions to take effect immediately.
Done !
For further details on the implementation of this extension, check the source code on GitHub. The most important source file is the applicationhost.xdt.
Quote from GitHub (02-08-2017) (credits go to gregjhogan):
applicationhost.xdt
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<location path="%XDT_SITENAME%" xdt:Transform="InsertIfMissing" xdt:Locator="Match(path)">
<system.webServer xdt:Transform="InsertIfMissing">
<rewrite xdt:Transform="InsertIfMissing">
<rules xdt:Transform="InsertIfMissing" lockElements="clear">
<rule name="redirect HTTP to HTTPS" enabled="true" stopProcessing="true" lockItem="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{WARMUP_REQUEST}" pattern="1" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</location>
</configuration>
R:1 is a back-reference to the rule pattern. You append that to the url here:
url="https://{HTTP_HOST}/{R:1}"
changing that into
url="https://{HTTP_HOST}"
should result in a redirect to the https root.

Run node.js & WebAPI on same server for same site with IIS

I'm looking to slowly convert a Node.js application over to ASP.NET WebAPI 2.0. I'm currently using IIS and will stick with IIS. So, I would like to host them on the same server but direct some URIs over to the new platform.
How would I do this in the web.config? The current web.config for node.js looks like so:
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application
to be handled by the iisnode module -->
<add name="iisnode" path="beta/app.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<!-- Don't interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^beta/app.js\/debug[\/]?" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="beta/public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the Node.js application entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="beta/app.js" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>
The file structure is:
- web.config (the one shown above)
-> node
- app.js
- ...
-> webapi
- web.config
- global.asax
- ...
I was thinking that I should be writing a new rule which lists the URIs to go to the WebAPI. But, I'm not quite sure how to do that. My guess is that I would add a condition for each URI with the input attribute. I was also thinking I should point to the ASP.NET WebAPI project but I am even more clueless how I should go about doing that since Node.js I'm just pointing at the app.js file.
OK, this is what I ended up doing. It was actually pretty straight forward. But when you are not familiar with IIS it can be daunting.
I put the original web.config in with the node directory. I think the iisnode handler interferes with WebAPI config if you don't. So, the new node.js web.config in the node directory would look like this:
<configuration>
<system.webServer>
<handlers>
<!-- indicates that the app.js file is a node.js application
to be handled by the iisnode module -->
<add name="iisnode" path="app.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^app.js\/debug[\/]?" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>
For root web.config I made it point to static files directly, bypassing node.js. Which means I'm going to have to write some custom code to handle rewrites for gzipped files - I'll figure that out later. I also added the attribute stopProcessing to each rewrite rule. This was also messing up the code, as it wouldn't actually rewrite where I wanted it too, since the rewrite would be overwritten. Note that the accept versioning header hasn't actually been tested yet - I don't have any reason to believe it wouldn't work though. The last rewrite points all uris to the webapi app by default.
In the WebAPI project I had to route all my routes to webapi/api since it isn't in the root folder. After I migrate everything from node.js I will probably make the webapi directory the root folder for the project so it won't need the webapi in my routing anymore. But this is all hidden from the client.
So here's the actual code:
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- test item for webapi folder -->
<rule name="StaticContent2" stopProcessing="true" >
<conditions>
<add input="{REQUEST_URI}" pattern="^/def" />
</conditions>
<action type="Rewrite" url="webapi{REQUEST_URI}" />
</rule>
<!-- rewrite static items which exist on node -->
<rule name="Node Static" stopProcessing="true" >
<conditions>
<add input="{REQUEST_URI}" pattern=".*\.[A-Za-z2]{2,5}$" />
</conditions>
<action type="Rewrite" url="node/public{REQUEST_URI}" />
</rule>
<rule name="WebAPI Version 2" stopProcessing="true">
<conditions>
<add
input="{HEADER_ACCEPT}"
pattern="vnd.fieldops.v2"
ignoreCase="true"
/>
</conditions>
<action type="Rewrite" url="webapi{REQUEST_URI}" />
</rule>
<!-- rewrite to node for dynamic items -->
<rule name="Node Dynamic" stopProcessing="true" >
<conditions>
<add
input="{REQUEST_URI}"
pattern="^/api/(dealerservicereports|chat|dealers|dealerequipment|dealercloseout|publications|tokens|users|\?)"
ignoreCase="true"
/>
</conditions>
<action type="Rewrite" url="node/app.js" />
</rule>
<!-- rewrite everything else to webapi -->
<rule name="WebAPI Dynamic" stopProcessing="true" >
<action type="Rewrite" url="webapi{REQUEST_URI}" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Detailed"/>
</system.webServer>
</configuration>

IIS redirect to full domain name

I need to redirect from
http://someserver/someapplication.page.aspx
to
http://someserver.domain.com/someapplication.page.aspx
Both the requests lead to the same server.
someserver/ works through our company's internal DNS
This is the same question as Redirecting to Full Domain
but I want an IIS solution for this, not code. My guess is it will have something to do with adding a httpRedirect add element in Configuration Editor using wildcards.
You can use URL Rewrite for that which is the recommended way to do it in IIS, simply add a web.config with a rule like:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect to full domain" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^someserver$" />
</conditions>
<action type="Redirect" url="http://someserver.domain.com/{R:0}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Resources