IIS URL Rewrite except specific site - asp.net

I have 3 sites (with different domains) which are hosted on one server, but all of them have same source and web.config. Sites 1 and 2 will be stopped and they should redirect to Site 4, but Site 3 will work as now...
I added a RewriteMap where described all pages redirects and a rule which is using that map:
<rewrite>
<rewriteMaps>
<rewriteMap name="My_RewriteMap" defaultValue="localhost/site4/Welcome.aspx">
<add key="/" value="localhost/site4/Welcome.aspx" />
<add key="/default.aspx" value="localhost/site4/Welcome.aspx" />
<add key="localhost/site2" value="localhost/site4/SpecificPage.aspx" />
<add key="/page3.aspx" value="localhost/site4/MyPage.aspx" />
<add key="new-page.aspx" value="localhost/site4/TheNewPage.aspx" />
...
</rewriteMap>
</rewriteMaps>
<rules>
<rule name="Redirect rule1 for My_RewriteMap" stopProcessing="true">
<match url=".*" negate="false" />
<conditions>
<add input="{My_RewriteMap:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
</rules>
</rewrite>
This code works for described pages in Map and for default value (if a specific page doesn't exist in the Map).
But this redirects Site 1, Site 2 and Site 3. I don't want to redirect to for Site3.
Is it possible with Rewrite URL feature?
I tried to edit match value with
<match url="localhost/Site3" negate="true" />
or
<match url="(localhost/Site3).*" negate="true" />
But both didn't work.
Thanks!

I Completed with next changes in conditions:
<conditions trackAllCaptures="true">
<add input="{HTTP_HOST}" pattern="localhost/Site3" negate="true" />
<add input="{My_RewriteMap:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
With the first condition, I say to ignore all requests where Host (in {HTTP_HOST} variable) contains the site's domain: localhost/Site3.
Then, the second condition works for the Map.

Related

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

IIS Re-write module not working for default document request

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/

IIS url rewrite, broken href (css, js etc)

I am using IIS url rewriting module in asp.net application, my problem is any internal relative references like js, css, images are now pointing to wrong url after this url rewrite, below is my rewriting rule
<rewrite>
<rules>
<rule name="pk" patternSyntax="ECMAScript">
<match url="pk/([a-z]+).aspx" />
<action type="Rewrite" url="{R:1}.aspx?mid=1" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" pattern="(\.css|\.js)$" negate="true" />
</conditions>
</rule>
</rules>
</rewrite>
In above rewrite any url with "pk/page_name.aspx" is being translated to page_name.aspx?mid=1, this is working fine, however references to js,css and images in master page are now also pointing to "pk/files/js/jquery.js" while in my application it should be "files/js/jquery.js", Please help me solve this issue.
I am able to solve this issue by myself, Earlier i was doing it completely wrong, I was doing just a rewrite which is causing problem, I solved this by first "Redirecting" the page to the desired URL and then "Rewriting" that URL to the one which my application understand. Following are my configuration
<rewrite>
<rules>
<rule name="Redriect for Markets" stopProcessing="true">
<match url="([a-z]+)\.aspx" />
<action type="Redirect" url="/{id:{C:1}}/{R:1}.aspx" appendQueryString="false" />
<conditions>
<add input="{REQUEST_FILENAME}" pattern="(\.css|\.js|\.jpg|\.png|\.woff|\.tiff|\.gif|\.dev|\.swf)$" negate="true" />
<add input="{QUERY_STRING}" pattern="mid=(.+)" />
</conditions>
</rule>
<rule name="Rewrite for Markets" stopProcessing="true">
<match url="([a-z][a-z])/(.*)" />
<action type="Rewrite" url="{R:2}?mid={marketId:{R:1}}" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_FILENAME}" pattern="(\.css|\.js|\.jpg|\.png|\.woff|\.tiff|\.gif|\.dev|\.swf)$" negate="true" />
</conditions>
</rule>
</rules>
<rewriteMaps>
<rewriteMap name="id">
<add key="1" value="pk" />
</rewriteMap>
<rewriteMap name="marketId">
<add key="pk" value="1" />
</rewriteMap>
</rewriteMaps>
</rewrite>
After doing this my URL which is like https://www.mydomain.com/index.aspx?mid=1 is first "Redirected" to https://www.mydomain.com/pk/index.aspx and then "Rewritten" to https://www.mydomain.com/index.aspx?mid=1 internally. So my browser window show URL as https://www.mydomain.com/pk/index.aspx and value I get in Request.QueryString["mid"] is 1, which is exactly what i wanted.
One thing more for internal URLs to work I have to take the base URL in master page currently it is set to "/"

How to URL Redirect "www.example1.com" & "www.example2.com" & "example2.com" to "example1.com" in IIS7

We are facing problems in URL Redirecting 4 URL's to a single URL.
The following is the mapping we need.
Entered URL -> Target URL
example1.com -> example1.com
www.example1.com -> example1.com
example2.com -> example1.com
www.example2.com -> example1.com
We are using IIS7 on WIn Srv 2008 SP1.
We now have all the bindings set in IIS. We have HTTPS. But for only the Target URL option we are having a valid certificate. All the rest of the options are shown as "This Connection is Untrusted" and the user has to manually click on the proceed to website. We want to redirect the user to the desired site even if the user types any of the URL's. I mean the User's URL in the browser should change to the target URL and the secured connection should open.
I have found URL Redirect 2.0 after googling for this. Will this solve my problem. Is it safe or is there any gotcha's involved in this.
Any better option without installing any.
TIA
Arun Kumar Allu.
I assume you have IIS "URL Rewrite" module installed, if so, then use these rewrite rules:
<rule name="AllToExample1Http" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.example1\.com$|^example2\.com$|^www\.example2\.com$" />
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="http://example1.com/{R:1}" />
</rule>
<rule name="AllToExample1Https" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.example1\.com$|^example2\.com$|^www\.example2\.com$" />
<add input="{HTTPS}" pattern="^ON$" />
</conditions>
<action type="Redirect" url="https://example1.com/{R:1}" />
</rule>
<configuration>
<system.webServer>
<defaultDocument>
<files>
<clear />
<add value="index.html" />
<add value="maintenance.htm" />
<add value="index.htm" />
<add value="Default.htm" />
<add value="Default.asp" />
<add value="iisstart.htm" />
<add value="default.aspx" />
</files>
</defaultDocument>
<httpRedirect enabled="false" destination="" exactDestination="false" />
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example1\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://example1.com/{R:0}"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

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