URL Rewriting in IIS with Express - express

I want to rewrite all images to a different folder. I'm using IIS and have configured a rule in the web.config to redirect all requests to a node.js file as follows:
<rewrite>
<rules>
<rule name="img">
<match url="\/(.*).img" />
<action type="Rewrite" url="/handlers/img.js" />
</rule>
</rules>
</rewrite>
All requests are now being sent to the img.js file, where based on a condition, I want to redirect to another image file. But IIS now sends that file to the img.js and it ends up as a loop. Is there any way out of this loop?

You could try the below thing to resolve the issue:
set the condition to do not match the pattern:
<conditions>
<add input="{REQUEST_URI}" pattern="\/(.*).img.js" negate="true" />
</conditions>
or set <rule name="img" stopProcessing="true">
<rule name="img" stopProcessing="true">
<match url="\/(.*).img" />
<conditions>
<add input="{REQUEST_URI}" pattern="\/(.*).img.js" negate="true" />
</conditions>
<serverVariables />
<action type="Rewrite" url="/handlers/img.js" logRewrittenUrl="true" />
</rule>

Related

IIS 10 (server 2016) SSL redirect to www. and .se

I have a site with multiple domainnames and have just implemented an ssl certificate to the site. but there is a problem when redirecting the incomming requests.
I want to configure it so all requests should redirect to one singel domainname (https://www.barnensbibliotek.se).
The ssl cert is for *.barnensbibliotek.se and www.barnensbibliotek.se and the other domainnames should just redirect to them regardless if the are http or https
i would like to redirect all other domainnames for barnensbibliotek like: barnensbibliotek.se, barnensbibliotek.com and www.barnensbibliotek.com (.info, .org, .nu, .net) to the https://www.barnensbibliotek.se.
I used this code in the web.config (this code works for www.barnensbibliotek.se but not for the others)
<rewrite>
<rules>
<rule name="Redirect to https" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" negate="false" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
Is there a way to solve this?
This problem was solved widt this code:
<rewrite>
<rules>
<rule name="http: to https" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
</rule>
</rules>
</rewrite>

IIS rewrite rule Redirect Non-www to dynamic Domain Equivalent and always https

What I want is that all requests that are non-https or don't have www prepended are redirected to: "https://www." + domain name + possible query string parameters.
I have this rewrite rule (found here):
<rule name="non-www to www https" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTP_HOST}" pattern="^[^\.]+\.[^\.]+$" />
<add input="{HTTPS}" pattern="on" />
</conditions>
<action type="Redirect" url="https://www.{HTTP_HOST}/{R:0}" />
</rule>
However, when typing the following domains in the browser address bar no redirect takes place (and I get a security certificate error since I don't have a wildcard DNS SSL certificate):
https://example.com/
http://example.com/
But example.com (without protocol), redirects correctly to https://www.example.com/
Also notice in the above rule that I'm matching the hostname dynamically and not just on "example.com" since I want this rule to work for multiple domain names.
I then also checked this post, which has a neat rule:
<rule name="Force WWW and SSL" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^[^www]" />
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://www.zzz.com/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
I think this does exactly what I want, but how would I make the domain name in this example dynamic and preserve that in the redirect (like the first code sample does)? (the original poster has not logged in in the last 6 months so that's why I am asking here)
Furthermore I also checked this post, which also seems a good candidate:
<rule name="Redirect top domains with non-www to www" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
<add input="{HTTP_HOST}" pattern=".*stage\..*" negate="true" />
<add input="{HTTP_HOST}" pattern=".*dev\..*" negate="true" />
<add input="{HTTP_HOST}" pattern="^([^\.]+)\.([^\.]+)$" />
</conditions>
<action type="Redirect" url="https://www.{HTTP_HOST}/{R:1}" redirectType="Permanent" />
<serverVariables>
<set name="Redirect" value="false" />
</serverVariables>
</rule>
<rule name="Force HTTPS" enabled="true" stopProcessing="true">
<match url="(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
<add input="{HTTP_HOST}" pattern=".*stage\..*" negate="true" />
<add input="{HTTP_HOST}" pattern=".*dev\..*" negate="true" />
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
But then http://example.com redirects to https://example.com and I still get the security exception.
First, I strongly recommend you to obtain a new SSL certificate that supports both example.com and www.example.com. That kind of certificates are actually pretty standard with most SSL providers, it does not have to be a wildcard certificate. Otherwise you will not be able to handle requests to https://example.com as it is now, and that's a problem I think.
Your top two rules should be like the ones below.
P.S. 301 redirects are cached for a while by the browsers. Google clear 301 redirect cache for your browser before testing the new rules.
<rule name="All HTTP to HTTPS+WWW" stopProcessing="true">
<match url=".*" />
<conditions trackAllCaptures="true">
<add input="{SERVER_PORT_SECURE}" pattern="0" />
<add input="{HTTP_HOST}" pattern="(?:localhost|stage\.|dev\.)" negate="true" />
<!-- here with this 3rd condition we capture the host name without "www." prefix into {C:1} variable to use in redirect action -->
<add input="{HTTP_HOST}" pattern="^(?:www\.)?(.+)" />
</conditions>
<action type="Redirect" url="https://www.{C:1}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>
<rule name="All HTTPS With No WWW to HTTPS+WWW" stopProcessing="true">
<match url=".*" />
<conditions trackAllCaptures="false">
<add input="{SERVER_PORT_SECURE}" pattern="1" />
<add input="{HTTP_HOST}" pattern="(?:localhost|stage\.|dev\.)" negate="true" />
<add input="{HTTP_HOST}" pattern="^www\." negate="true" />
</conditions>
<action type="Redirect" url="https://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>

IIS URL Rewrite

I have the following rewrite rule:
<rewrite>
<rules>
<rule name="FrontController" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wcf/api.svc/auth/home" />
</rule>
</rules>
</rewrite>
This basically rewrites all non-file urls to web service api calls that returns index.html in an SPA backed by WCF.
The above rewrite ends up including all the query string parameters that were included with the original URL. What I need to do is also include the original URL, such as, 'wcf/api.svc/auth/products', as a query string parameter in the rewritten URL, such as 'https://domain.com/wcf/api.svc/auth/products?enc=lkjewro8xlkz' being transformed into 'https://domain.com/wcf/api.svc/auth/home?enc=lkjewro8xlkz&orig=wcf/api.svc/auth/products'.
Is this possible, and if so, what changes would I need to make to achieve it? I would like for my WCF application to know about the original URL so that it can configure the SPA to initialize to a particular view on load.
Thanks
It's quite possible.
You need to add the URL Encoded value of the {REQUEST_URI} to the Rewrite URL.
<rewrite>
<rules>
<rule name="FrontController" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="wcf/api.svc/auth/home?orig={UrlEncode:{REQUEST_URI}}" />
</rule>
</rules>
</rewrite>
With this rule, in your WCF endpoint orig parameter would be:
/wcf/api.svc/auth/products?enc=lkjewro8xlkz
If you don't want the query string part (?enc=lkjewro8xlkz), you'll need an extra condition to match the URI without query string.
<rewrite>
<rules>
<rule name="FrontController" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<!-- match any character up to a question mark -->
<add input="{REQUEST_URI}" pattern="^[^\?]+" />
</conditions>
<!-- {C:0} means the first match in conditions -->
<action type="Rewrite" url="wcf/api.svc/auth/home?orig={UrlEncode:{C:0}}" />
</rule>
</rules>
</rewrite>
Now, orig will be /wcf/api.svc/auth/products in the WCF endpoint.
Hope it helps.

Preserving URL when using SSL Redirect for multiple websites pointing to same folder

I have multiple websites pointing to a central folder (IIS 7.5)
company1.domain.com/wo pointing to D:\inetpub\wo
company2.domain.com/wo pointing to D:\inetpub\wo
company3.domain.com/wo pointing to D:\inetpub\wo
All the websites work for both HTTP and HTTPS (if typed manually). However, the sites have to connect via HTTPS. I want to setup automatic SSL redirect to but am having issues. I created URL Rewrite rule but since this is only one webconfig file the URL redirects to only one website (not maintaining the URL).
How do I setup SSL redirect so that the URLs are preserved and all websites point to the same folder?
Any assistance will be greatly appreciated.
Thanks
You should include the host header when checking if HTTPS is enabled and then redirect to the https URL for the appropriate domain.
Here's an example:
<rewrite>
<rules>
<clear />
<rule name="Force HTTPS - www.domain1.com" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" negate="true" pattern="^ON$" />
<add input="{HTTP_HOST}" pattern="\.domain1\.com$" />
</conditions>
<action type="Redirect" url="https://www.domain1.com{REQUEST_URI}" appendQueryString="false" redirectType="Permanent" />
</rule>
<rule name="Force HTTPS - www.domain2.com" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" negate="true" pattern="^ON$" />
<add input="{HTTP_HOST}" pattern="\.domain2\.com$" />
</conditions>
<action type="Redirect" url="https://www.domain2.com{REQUEST_URI}" appendQueryString="false" redirectType="Permanent" />
</rule>
<!-- add more rules for other domains if needed -->
</rule>
</rules>
</rewrite>
You can add as many rules for domain names as you want.
EDIT: Sorry, I misread your question. In that case it's even simpler:
<rewrite>
<rules>
<clear />
<rule name="Force HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" negate="true" pattern="^ON$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
No need to check for the host header, just include the host name in the redirect. You only have to make sure that you have SSL certificates for all domain names.

Url rewriting not working as expected

I am trying to rewrite the rule so that if no .svc comes in URL it should rewrite and append .svc in URL.
These are my rules:
<rewrite>
<rules>
<rule name="RemoveSVC" stopProcessing="true">
<match url="localhost/RestApp/Services/([a-zA-Z0-9]*)/(.*)$" />
<action type="Rewrite" url="localhost/RestApp/Services/{R:1}.svc/{R:2}"
appendQueryString="true" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
Can anybody tell me why is this rule not working?
I think you want:
<rewrite>
<rules>
<rule name="RemoveSVC" stopProcessing="true">
<match url="localhost/RestApp/Services/([a-zA-Z0-9]*)/(.*)" />
<action type="Rewrite" url="localhost/RestApp/Services/{R:1}.svc/{R:2}"
appendQueryString="true" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
Remove the $ sign on the end.
I'd also get rid of the localhost/ part because that would only work on your local dev PC, when you deploy into production it won't be localhost any more:
<match url="RestApp/Services/([a-zA-Z0-9]*)/(.*)" />
<action type="Rewrite" url="RestApp/Services/{R:1}.svc/{R:2}"
appendQueryString="true" logRewrittenUrl="true" />