IIS Re-write module not working for default document request - asp.net

I'm trying to use the IIS rewrite module to redirect HTTP to HTTPS for certain areas of my site.
It works mostly. However I've noticed a strange inconsistency if the request uses the default document.
For example...
http://[mydomain]/test_folder/default.aspx
correctly redirects to...
https://[mydomain]/test_folder/default.aspx
However, this URL...
http://[mydomain]/test_folder/
does not redirect.
My re-write rules are defined as follows...
<rewrite>
<rules>
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^mydomain.com$" ignoreCase="true" />
<add input="{SCRIPT_NAME}" pattern="^/(?:admin|test_).*" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
My default documents are defined as follows...
<defaultDocument enabled="true">
<files>
<clear />
<add value="default.asp" />
<add value="default.aspx" />
</files>
</defaultDocument>
It's like having processed the request for the default document, it doesn't bother to process my rewrite rules.
Can anyone suggest what I might be doing wrong, and how to resolve it?
Update: I've been able to work around the problem by removing the rewrite rules, and instead doing the redirection in global.asax. This seems like a slightly hacky way to do it though, so I would prefer to use IIS rewrite if there is a proper solution.

This rule will redirect all requests which stars with admin or test_:
<rule name="redirect to HTTPS" stopProcessing="true">
<match url="^(admin|test_)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^mydomain.com$" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}"/>
</rule>
Example:
http://[mydomain]/test_folder/default.aspx to https://[mydomain]/test_folder/default.aspx
http://[mydomain]/admin/default.aspx to https://[mydomain]/admin/default.aspx
http://[mydomain]/test_folder/ to https://[mydomain]/test_folder/

Related

URL Rewrite to a subdomain

I am using the Rewrite tool for ASP.NET to redirect from http to hpps. I want to reroute to
https://services.net/ExitInterview/home/about
But currently it is routing to
https://services.net/home/about
Below is my redirect rule:
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>`
Can I mix the "HTTP_HOST" text with hard-coded text in the rule string? Or is there another way?
I don't want to hard code the url because it changes with local, staging, and production.
<rule name="HTTP to HTTPS redirect" ="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/ExitInterview/{R:1}"
redirectType="Permanent" />
</rule>
Give this a try
This should do what you want in terms of redirecting to HTTPS from HTTP in a web.config file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<httpRuntime executionTimeout="180" />
</system.web>
<system.webServer>
<httpErrors errorMode="Detailed" existingResponse="PassThrough" />
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I use this exact snippet for a webserver that enforces HTTPS redirection, but that also seems to be pretty close to what you have. Are you sure you have configured the structure of the web.config file correctly? - I remember running into issues when I would leave out something.

Prevent subdomain from redirecting to HTTPS

I have the following rewrite rule in my web.config when the production transform is applied.
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="Redirect-HTTP-TO-HTTPS" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
When I deploy a separate website with the staging transform to the same IIS instance, this rule doesn't get added to my web.config. Yet traffic to staging.example.com still get's caught by the rule.
It seems the production rule is still catching it?
Production url: example.com
Staging url: staging.example.com
How would I make this rule a little less greedy, so it doesn't redirect staging traffic.
You can add additional condition to your rule to ignore staging.example.com:
<rule name="Redirect-HTTP-TO-HTTPS" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" pattern="off" />
<add input="{HTTP_HOST}" pattern="^staging\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Found" appendQueryString="true" />
</rule>
Keep in mind, that browsers often cache 301 redirects. After you applied this rule please clear your browser's cache or use incognito mode

IIS Query string lost when using URL Rewrite rules

I am trying to get a site to work with a different URL, basically one is the real URL(fakesite.com) and the other is a Branded URL(NewFakeSite.com). So far ive managed to get it to work so that:
http://fakesite.com/uv/ExpressBranding/ExpressHome.aspx
and
http://NewFakeSite.com/uv/ExpressBranding/ExpressHome.aspx
Both go to the same site and are both able to work as functioning sites. The Problem comes with Querystrings, I cant seem to get the second site to pass along the Querystring so if I go to a URL with a Querystring like:
http://fakesite.com/uv/EnviSetup/Wizard/GeneralInformation.aspx?DashboardId=0
For the Second site it cant find the page and instead gives me:
https://NewFakeSite.com/uv/EnviSetup/Wizard/GeneralInformation.aspx
with no QueryString at all.As such I need to add the Querystring. My webconfig is below, its not just my code so certain pieces of it like the HTTP to HTTPS and adding uv were not written by me.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<remove name="Redirect to HTTPS" />
<remove name="Redirect to add uv folder to dotcom" />
<rule name="Redirect to add uv folder to dotcom" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{map add uv after dotcom:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<serverVariables />
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
<rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{SERVER_NAME}" pattern="opterra\.esightenergy\.com" negate="true" />
</conditions>
<serverVariables />
<action type="Rewrite" url="https://{HTTP_HOST}/{R:1}" appendQueryString="false" />
</rule>
<rule name="AddQueryStringForENVIDashBoards">
<match url="https://prod.utilityvision.com/uv/EnviSetup/EnviDashboardList.aspx(\?(.*))" />
<action type="Rewrite" url="HTTPS://opterra.esightenergy.com/uv/EnviSetup/Wizard/{C:1}" appendQueryString="false" />
<conditions>
<add input="{URL}" pattern="https://prod.utilityvision.com/uv/EnviSetup/Wizard/(.*)" />
</conditions>
</rule>
</rules>
</rewrite>
<httpRedirect enabled="false" destination="" exactDestination="false" childOnly="false" />
</system.webServer>
</configuration>
Any Help would be greatly appreciated I am new to IIS so I hope this is even possible. Thanks!
EDIT: I have tried setting the appendQueryString="True" but still no Querystring. Thanks mjw.
Edit 2: The main goal is to make make it so the URL shows up as something different then it was originally programmed as, The problem is the Query String doesnt come with the rest of the new URL. I have added some code changes to see if this would fix the problem but it did not the URL remained the same. The code sample above is not the original I added this:
<rule name="AddQueryStringForENVIDashBoards">
<match url="https://prod.utilityvision.com/uv/EnviSetup/EnviDashboardList.aspx(\?(.*))" />
<action type="Rewrite" url="HTTPS://opterra.esightenergy.com/uv/EnviSetup/Wizard/{C:1}" appendQueryString="false" />
<conditions>
<add input="{URL}" pattern="https://prod.utilityvision.com/uv/EnviSetup/Wizard/(.*)" />
</conditions>
</rule>
You have server variable for query string so you can use it to append value to the redirection url:
QUERY_STRING
So for your request http://fakesite.com/uv/EnviSetup/Wizard/GeneralInformation.aspx?DashboardId=0
Important Server variable values are:
HTTP_HOST: www.fakesite.com
PATH: /uv/EnviSetup/Wizard/GeneralInformation.aspx
QUERY_STRING: DashboardId=0
Also if you open IIS->Url Rewrite and go to your rule you will see there is a option to test rule, you can simply paste your url and have an overview how URL is parsed. You will then also realize which part you can use to append query string.
http://www.iis.net/learn/extensions/url-rewrite-module/testing-rewrite-rule-patterns

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

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.

IIS7 URL Rewriting: How not to drop HTTPS protocol from rewritten URL?

I'm working on a website that uses IIS 7's URL rewriting feature to do a permanent redirect from example.com to www.example.com, as well as rewrites from similar domain names to the "main" one, such as from www.examples.com to www.example.com.
This rewrite rule - shown below - has worked well for some time now. However, we recently added HTTPS support and noticed that if users visit one of the URLs to be rewritten to www.example.com then HTTPS is dropped. For instance, if a user visits https://example.com they get redirected to http://www.example.com, whereas we would like them to be sent to https://www.example.com.
Here is the rewrite rule of interest (in Web.config):
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^example\.com$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.net$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?example\.info$" />
<add input="{HTTP_HOST}" pattern="^(www\.)?examples\.com$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
As you can see, the action element's url attribute points directly to http://, so I get why https://example.com is redirected to http://www.example.com. My question is, how do I fix this? I tried (naively) to just drop the http:// part from the url attribute, but that didn't work.
Here's Scott's answer with Hasan's improvements. This should cover mixed SSL/non-SSL sites. The rule basically says "if the url does not have www.example.com", do a permanent redirect to it. Essentially... you are redirecting people who visit you without www or directly to your IP address.
<rewrite>
<rules>
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
</conditions>
<action type="Redirect" url="{MapSSL:{HTTPS}}www.example.com/{R:1}" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapSSL" defaultValue="http://">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
</rewriteMaps>
</rewrite>
Figured out the answer with some help from my colleagues.
I needed to use multiple rules with a condition on {HTTPS}. Note the {HTTPS} condition in the rules below.
<rule name="Canonical Host Name (HTTP)" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="OFF" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name (HTTPS)" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTPS}" pattern="ON" />
<add input="{HTTP_HOST}" pattern="^example\.com$" />
</conditions>
<action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>
I then repeated the rule pair above for the alternate domain names.
If you just want to redirect based on the currently used protocol (as per your last sample) then there's a much simpler solution that will halve the amount of rules you will need. The following is what I've learned from a collegue of mine.
As you've seen, the {HTTPS} argument will contain the value ON or OFF. You can map this value to https:// or http:// by feeding this value into a rewritemap.
Here's how this would work:
1- Create a rewritemap section for mapping the {HTTPS} value:
<rewriteMap name="MapProtocol" defaultValue="OFF">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
It's up to you to decide if you want to only include the protocol, or the semicolon and forward slashes as well. It doesn't matter for the solution, but keep it in mind wherever you refer to it.
2- Refer to this map wherever you need. In this sample it's used in outbound-rules, but it'll also work in your scenario:
<rule name="Outbound-Rule Name" stopProcessing="true" preCondition="ResponseIsHtml">
<match filterByTags="A, Link, Script" pattern="YOUR PATTERN" />
<action type="Rewrite" value="{MapProtocol:{HTTPS}}{HTTP_HOST}/REST OF RELATIVE LINK HERE" />
</rule>
That's it, the URL Rewrite module should now automagically use the correct protocol for your links depending on if you're using https, or, of course, http.
Hope this helps!
Here's a cross-domain solution which works not only on example.com but also on any domain
<rewrite>
<rules>
<rule name="Canonical Host Name" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^www\.([.a-zA-Z0-9]+)$" negate="true" />
</conditions>
<action type="Redirect" url="{MapProtocol:{HTTPS}}www.{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="MapProtocol" defaultValue="OFF">
<add key="ON" value="https://" />
<add key="OFF" value="http://" />
</rewriteMap>
</rewriteMaps>
</rewrite>

Resources