Having trouble getting ASP.NET URL rewrite to exclude a specific file - asp.net

I want to redirect all HTTP requests to my site to HTTPS except for the file "/blah.txt". Here's the basic rewriting rule I've been trying. I've tried to use {REQUEST_FILENAME} and {URL}. I've tried several different patterns that I thought should match.
The rule below redirect every request to HTTPS including requests for blah.txt
<rewrite>
<rules>
<clear />
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{REQUEST_FILENAME}" matchType="Pattern" pattern="blah\.txt$" ignoreCase="true" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>

Thanks Bryan for changing my direction of thought. Sometimes I get stuck thinking that my solution will work based on bugless code. In fact it appears that there is a bug in the rewriter that makes my first attempt at writing a rule fail. However, this rule DOES work:
<rewrite>
<rules>
<clear />
<rule name="Temp" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" pattern="blah\.txt$" />
</conditions>
<action type="None" />
</rule>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
Putting the matching rule in front of the other rule and causing it to stop processing of rules seems to work.

I only see one rule... that seems to match everything. You need at least two rules here.
I'm not that familiar with IIS rewrite's feature. So two questions:
Is there a "do nothing" action?
Won't any all-inclusive rule match ALL requests? You probably need to put your blah.txt rule first.

Related

IIS Redirect HTTP to HTTPS and WWW to non-WWW

On IIS 10 with URL Rewrite Module 2.0 I need 2 rules
1) HTTP to HTTPS
2) WWW to non-WWW
First one created by Blank rule template.
For second one I use Canonical domain name template.
In my web.config rules likes like this:
<rewrite>
<rules>
<rule name="ForceHttps" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="CanonicalHostNameRule1" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^cooltechunder\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://cooltechunder.com/{R:1}" />
</rule>
</rules>
</rewrite>
All cases works fine expect one starting with: http://www.
See this image for results I have:
https://i.imgur.com/h2l3Yw6.png
You wrote stopProcessing="true".
This means that, if the rule matches, subsequent rules will be skipped.
From the documentation:
A rule may have the StopProcessing flag turned on. When the rule action is performed (i.e. the rule matched) and this flag is turned on, it means that no more subsequent rules will be processed and the request will be passed to the IIS request pipeline. By default, this flag is turned off.
It seems to me that this is the situation you are describing that you did not want.
So, remove it.
Ok, My problem was different and related to bindings.
I have to specify 'Host Name' in bindings, as specific ports used by other websites also
And I forgot to add 'www' versions of bindings also.
Now my bindings looks like this: https://i.imgur.com/Lhdv4nS.jpg
Also I have changed rewrite code to more compact one:
<rewrite>
<rules>
<rule name="Https and non-www">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^cooltechunder\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://cooltechunder.com/{R:1}" />
</rule>
</rules>
</rewrite>

"non-www to www" and "https" rewrite rule in web.config but not localhost ASP.NET MVC

I have the following rewrite rule in the web.config of my ASP.NET MVC 5 project:
<rule name="Redirect example.com to www.example.com and enforce https" 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.example.com/{R:1}" appendQueryString="true" redirectType="Permanent" />
</rule>
The rule redirects non-www to www and http to https (so something like http://example.com/hey will redirect to https://www.example.com/hey) and works fine. It however also works on localhost, and I can't seem to be able to work around it — I've tried negation rules and regular expressions containing | but can't seem to be able to find the correct combinations. Am I approaching this the wrong way?
In conditions block you can use attribute negate="true". If this attribute is set and condition is matched, then rewrite rule is not applied.
The description of negate attribute from IIS.net:
A pattern can be negated by using the negate attribute of the
element. When this attribute is used, the rule action is performed
only if the current URL does not match the specified pattern.
Since you are using MatchAny, adding additional attribute will not match, because at least one of the conditions will be met anyway. I recommend using 2 specific rewrite rules with logicalGrouping="MatchAll", where each one is responsible just for single case:
<rule name="enforce https" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" pattern="off" />
<add input="{HTTP_HOST}" matchType="Pattern"
pattern="^localhost(:\d+)?$" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
appendQueryString="true" redirectType="Permanent" />
</rule>
<rule name="Redirect example.com to www.example.com"
enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^[^www]" />
<add input="{HTTP_HOST}" matchType="Pattern"
pattern="^localhost(:\d+)?$" negate="true" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:1}"
appendQueryString="true" redirectType="Permanent" />
</rule>

IIS Re-write http to https with subfolders

As simple as it sounds and as much as I've searched, I'm not able to get
http://example.com/subfolder to redirect to https://example.com/subfolder using IIS rewrite.
Note: This is only when "http" is explicitly stated in the browser.
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" />enter code here
Thanks!
The problem with your rule is that REQUEST_URI in your redirect action is the whole URI as requested. What you want is the result of the rule match. R1 will give you this. This answer gives a good explanation of the rule back-references. A working rule can be constructed like this:
<rewrite>
<rules>
<rule name="HTTP to HTTPS Redirect" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>

IIS rewrite rule to redirect https to http not working

There's lots of questions here about redirecting http to https so I figured it would be easy to reverse the process. However, everything I've tried hasn't worked.
I'm trying to combine the rule with my canonical host name rule (it's the first rule, at the top of the rewrite rules):
<rule name="CanonicalHostName" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="^ON$" />
<add input="{HTTP_HOST}" negate="true" pattern="^www\.example\.com|example-staging\.azurewebsites\.net$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
The site is hosted on Azure and DNS is with CloudFlare if that makes any difference, I'm sure it shouldn't.
Any ideas what I'm doing wrong / might be preventing the https to http part of the rule working? (the host name part works fine)
CloudFlare
It seems the reason you cannot redirect away from SSL is because you are using CloudFlare. CloudFlare at a minimum uses flexible SSL. This means that the end user, browser shows the SSL lock but your server doesn't need SSL. See documentation here: https://www.cloudflare.com/ssl
Without CloudFlare the following example should work.
No CloudFlare
The following rule should work. You could still add your negate in if you want.
<rule name="HTTPS to HTTP redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://{HTTP_HOST}/{R:1}" />
</rule>
Full rewrite section for my working demo site.
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.ashleymedway\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.ashleymedway.com/{R:1}" />
</rule>
<rule name="HTTPS to HTTP redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="on" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{R:1}" redirectType="Found" />
</rule>
</rules>
</rewrite>
Your redirect is still http:
url="http://www.example.com/{R:1}"
You can follow these instructions: Click Here
Additional information: Here

Rewriting URLs from https:// to http:// in IIS7

I'm trying to rewrite urls from the form:
https://example.com/about
to the form
http://example.com/about
using IIS7 URL rewriting:
<!-- http:// to https:// rule -->
<rule name="ForceHttpsBilling" stopProcessing="true">
<match url="(.*)billing/(.*)" ignoreCase="true" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="false" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}{REQUEST_URI}" />
</rule>
<!-- https:// to http:// rule -->
<rule name="ForceNonHttps" stopProcessing="true">
<match url="(.*)billing/(.*)" ignoreCase="true" negate="true" />
<conditions>
<add input="{SERVER_PORT}" pattern="^443$" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://{HTTP_HOST}{REQUEST_URI}" />
</rule>
I'm at a loss; I've been browsing the web for examples and trying every syntax I can think of. The rewrite rules I specify simply don't appear to work at all for any https requests, as if all the https:// requests are flat out invisible to the rewrite engine.
rules work fine; see answer below.
Turns out that I had port :443 bound to a different website!
The above rewrite rules work fine for http:// to https:// rewriting and vice-versa -- though there might be more optimal or simple ways to do it.
Leaving this question here for future voyagers to find, as I didn't see many good examples of the https:// to http:// rewriting scenario on the web.
This post is a little old, but I wanted to answer. I am using ASP.Net MVC3, and Fabio's answer above didn't work for me. The easiest solution I came up with to handle the https redirect to http, while still allowing valid https pages to request secure content was just to add Whitelist rules above my https/http redirects:
<rule name="WhiteList - content folder" stopProcessing="true">
<match url="^content/"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false"/>
<action type="None"/>
</rule>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)billing/(.*)" ignoreCase="true" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/billing/" redirectType="SeeOther" />
</rule>
<rule name="ForceNonHttps" stopProcessing="true">
<match url="(.*)billing/(.*)" ignoreCase="true" negate="true" />
<conditions>
<add input="{SERVER_PORT}" pattern="^443$" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://{HTTP_HOST}{REQUEST_URI}" />
</rule>
please first consider binding https to your website for making below redirect module to work is essential (so bind your web app with a self-signed or valid certificate)
final part in web.config to redirect https to http:
<rewrite>
<rules>
<rule name="Force NonHTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="on" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{REQUEST_URI}" />
</rule>
</rules>
</rewrite>
if you need the equivalent IIS GUI in rewrite module see below image
source: look tech-net for more detail and step by step guide.
Your solution work, but the problem is: your second instruction kill first instruction for any links is not (.)billing/(.), including your css, js, and images.
You can use this https to http rule:
<rule name="HTTPS to HTTP redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{RequiresSSL:{R:1}}" pattern="(.+)" negate="true" />
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
<add input="{REQUEST_URI}" pattern="^(.+)\.(?!aspx)" negate="true" />
</conditions>
<action type="Redirect" redirectType="Found" url="http://{HTTP_HOST}/{R:1}" />
</rule>

Resources