IIS URLRewrite Regular Expression - regex

I am horrible with regular expressions and new to the URL Rewrite module in IIS so please bear with me...
I have a scenario where I have 1-2 pages that I need to be redirected to a specific location and protocol (https).
Desired URL
https://www.domain.com/specific/location/mypage.aspx
I need to make sure users are hitting this specific url when trying to access this page. So any of the below should redirect the user to my "desired" url:
http://www.domain.com/specific/location/mypage.aspx
http://domain.com/specific/location/mypage.aspx
https://domain.com/specific/location/mypage.aspx
http://www.anotherDomain.com/specific/location/mypage.aspx
http://anotherDomain.com.com/specific/location/mypage.aspx
https://anotherDomain.com.com/specific/location/mypage.aspx
I need this to happen for this page and one other page and I need to make sure only these pages are being redirected to ssl, so the rest of the site should be redirected to its http version if the user types in https. How can I accomplish this, do I need more than one rule, etc?
Any help is greatly appreciated.

Thankfully, this isn't as complicated as it looks. When creating rules using the IIS URL Rewrite module, the "url" in the match tag is only looking at everything after the host name. It doesn't see the domain.com.
So, in your web.config, within the system.webserver section, in your rewrite section:
<rule name="Redirect Specific Location" enabled="true" stopProcessing="true">
<match url="specific\/location\/mypage\.aspx"/>
<action type="Redirect" url="https://www.domain.com/specific/location/mypage.aspx"/>
</rule>
That way any URL coming in that ends with specific/location/mypage.aspx will be redirected, no matter what the hostname is.

Related

IIS redirect rule not catching specified RegEx

I am trying to configure a Redirect Rule for our IIS server.
I have examined all the documentation as well as several other examples on the site, however I cannot seem to get the requested URL to capture when the pattern matches. I tried testing the regex inside the IIS rule editor and it shows that it matches correctly. I also set up some conditions and tested them however, it seems to not work either.
here is the rule in xml
<rule name="product_detail.asp redirect to aspx" stopProcessing="true">
<match url="http:\/\/ten\.perle\.com\/products\/product_detail.asp\?(.*)&(.*)&(.*)" />
<conditions>
<add input="{QUERY_STRING}" pattern="http:\/\/ten\.perle\.com\/products\/product_detail.asp\?(.*)&(.*)&(.*)" />
</conditions>
<action type="Redirect" url="products/product_detail.aspx?{C:1}&{C:2}&{C:3}" appendQueryString="false" />
</rule>
sample url http://ten.perle.com/products/product_detail.asp?a=2&i=08000514&c=1650
I don't understand what exactly I am doing wrong It appears as though my regex should catch the request but for some reason it never seems to.
I feel like there seems to be some problem with your URL rule.
For example, Send a request to the following URL:
http://ten.perle.com/products/product_detail.asp?id=123&name=test
The Pattern in the Match URL should be the path part of the URL:
products/product_detail.asp
The QUERY_STRING server variable matches the part of the URL's
parameter string: id=123&name=test
You can try to modify your rule and see if it works.
In addition, You can use Failed Request Tracing in IIS to troubleshoot. The log file in the FailedReqLogFiles folder can see the whole process of rewriting in detail, and can check where the match fails.
So the Issue was solved using the below rule
<rule name="product_detail.asp redirect" stopProcessing="true">
<match url="^(products/product_detail.asp?)([^x]+)$" />
<action type="Redirect" url="products/product_detail.aspx?{R:2}" />
</rule>
Some things That I would like to include in case anyone else faces a similar issue. Some things to clarify.
the match URL portion should include the relative path of the URL you're going to be redirecting. In my initial attempts I was unsure if to include a full path or just the relative portion. This isn't fully clear in any of the documentation, at least its not explicitly stated anywhere i could find.
The redirect URL needs to contain everything required after the base URL for the new URL. Including parameters if required either pulled via rules {R:x} or from the conditions {C:x}
It took me some time to understand the parameter capturing, this is based on the regEx, if you test it it will show you how the url match is broken up into numbered rules based on your regEx
I ended up not need the query string condition for my use case, it was simpler for me to use the rules capture from the initial pattern.
also btw was working on IIS v10.0
Hope this helps some other beginners looking to do this and clarify some more of the less obvious aspects of IIS redirects.

IIS rewrites and handlers conflict

I'm trying to set up a Django/Angular application under IIS.
When I set a similar application under nginx, I pass all URLs starting with /api (my backend) or /admin (the Django admin interface) to Django. I also set two locations: / and /static - both are aliases to the folder with all the static resources.
I need to alias /static, too, because Django's admin application references resources at /static/admin/...
I can't get IIS to work the same way. I'm using wfastcgi to interface with Django, and a rewrite rule to map /static back to /. This is the relevant portion of my Web.config:
<rewrite>
<rules>
<rule name="Static Perfix" stopProcessing="true" >
<match url="^static/(.+)" />
<action type="Rewrite" url="{R:1}" />
</rule>
</rules>
</rewrite>
<handlers>
<add name="Admin"
path="/admin"
verb="*"
modules="FastCgiModule"
scriptProcessor="..."
resourceType="Unspecified" />
</handlers>
This doesn't work. When I access /admin the handler catches it and forwards the request to Django, as it should. Django return an html page with resources located at /static/admin/base.css (for example).
When the browser tries to load such a resource the rewrite rule catches it, rewrites it to /admin/base.css, and then the handler catches it and forwards it to Django, which doesn't know what /admin/base.css is and returns a 404.
I tried making /static a Virtual Directory pointing to the same physical directory as the root directory. This caused all sorts of conflicts because my root Web.config was read twice, causing all sorts of duplicate key violations (for all the keys I have defined, more or less).
I would appreciate any help on getting out of this situation.
I ended up avoiding the problem altogether, by restructuring my static resources folder and adding an actual static subfolder that contains the Admin static files.
I will no longer be able to use manage.py collectstatic for front-end deployment, though, I will need to create an additional script. Oh well.

IIS Request Filtering Allow URL

I am using IIS7 request Filtering (WebSite level) with 'Allow unlisted file name extensions' set to un-checked. After this setting when I access my web application say, _http:/machine_name/app1 then it fails. After adding correct file extensions under 'file name extensions' it starts functioning but it later fails when I surf other links inside my application. I found that I need to add URL's under 'Allow URL' but I do have huge number of URL list which need to be added for e.g.:
'/app1/prop1', '/app1/prop1/services/', '/app1/prop2/repository'..... and more
So, I see a pattern like /app1/* but 'allow URL don't allow any pattern matching. Is there any way to add Regular expression somewhere in IIS so that the matching URL's can be allowed.
Thanks in advance.
I think URLs like '/app1/prop1', '/app1/prop1/services/', '/app1/prop2/repository' don't work with 'Allow unlisted file name extensions' set to false because you didn't allow extensionless requests.
To allow extensionless requests, add <add fileExtension="." allowed="true" /> to your web.config as below:
<system.webServer>
<security>
<requestFiltering>
<fileExtensions allowUnlisted="false">
<add fileExtension="." allowed="true" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
Please let me know if this helped or the issue still occurs.
OK, at last I got the solution. The trick was not using 'requestfiltering' but 'URL rewrite'. It has the option to allow or deny URL based on the regular expression or Wildcard with the option 'Does not match the pattern'. I created rule for the URL/file which does not matches my application's pattern and deny those by redirecting a 404 type of error.
#alexander-abakumov is correct. When allowUnlisted=false, one must include the provided xml (<add fileExtension="." allowed="true" />) to allow extension-less requests (e.g. /App/ or /Folder/).
Request Filtering Limitations
You're correct to use URL Rewrite for achieving RegEx pattern matching. Below are the limitations of Request Filtering.
Stateless - Request Filtering has no knowledge of application or session state. Each request is processed individually regardless of whether a session has or has not been established.
Request Header Only - Request Filtering can only inspect the request header. It has no visibility into the request body or any part of the response.
Basic Logic - Regular expressions and wildcard matches are not available. Most settings consist of establishing size constraints while others perform simple string matching.
Still use Request Filtering
I would still recommend using Request Filtering since it operates so early in the IIS request pipeline; even before URL Rewrite. This gives you the opportunity to immediately discard bad requests. URL Rewrite can then be a second layer of request filtering.
IISRFBaseline
The information above is based on my PowerShell module IISRFBaseline. It helps establish an IIS Request Filtering baseline by leveraging Microsoft Logparser to scan a website's content directory and IIS logs.
For the fileExtensions setting there are two methods for establishing a baseline:
IIS Logs - by parsing prior successful requests and determining the extension of the request.
Content Directory - scanning the file system of the website content directory to see what file extensions are in use.
There are caveats to these two approaches which are described in more detail here. With two techniques, a markdown file is provided describing the methodology of each as denoted by the suffix IIS or FS.
fileExtensions_FS
fileExtensions_IIS
The result of these two techniques are combined, after removing bad requests, to create a baseline for this Request Filtering setting.

Microsoft IIS URL Rewrite - regex

Im currently working with my IIS Server and ive installed the IIS rewrite module.
I currently have a rule on it which allows for all my coldfusion templates to be parsed really easily.
it generates the following pattern
^([^/]+)/?$
which covers any request for any template on the following page
index.cfm?action={R:1}
This rule simply parses any request into my website and makes it go directly to my index.cfm page.
What Im trying to understand is how to get the following.
^/css/ - then any script or sub folder to process like any other page request
^/js/ - then process any js file as it is stored on my server
^/assets/ - process any file in this folder as a normal file.
Ive never used this module before but im struggling to find out how to treat normal files like js and css as they are and in their respective directories.
I have no problem in writing the rules so each is prefixed with the folder names but cant for the life of me work out where to get any information on this from.
As long as you specify a rule before the one that catches everything, you should be able to use the stopProcessing attribute to prevent the module from doing anything with the request. There's no need to specify an action. For example:
<rule name="CSS files" stopProcessing="true">
<match url="^/css/" />
</rule>
Here is for all static files
<rule name="Static Files" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll">
<add input="{SCRIPT_NAME}" pattern="\.(bmp|gif|jpe?g|png|css|js|txt|pdf|doc|xls)$" ignoreCase="true" />
</conditions>
<action type="None" />
</rule>
Update:
I am sorry, I haven't notice you have asked for folder. But I keep in answer in case other people like to know about it.

Is this a valid regular expression in IIS 7?

Further to my question at How do write a rewrite rule in IIS that allows HTML anchors? I was wondering if I can do the following or alternatively if there is a similar option to what is available in Apache e.g. mod_rewrite with anchor link
<match url="^ts\/tcs\.aspx$" />
<action type="Redirect" url="http://www.abc.com" />
<conditions>
<add input="{UrlEncode:{URL}}" pattern="#" />
</conditions>
Here we go:
Everything after the hash (including the hash symbol itself) will NOT be sent to a server (it is client-side ONLY), therefore you cannot match it in any way.
It is not IIS restriction -- any web server does (better say, should do) the same -- the browser itself should not send it to a server in first place. Of course -- if you send such request manually via custom code (PHP, ASP.NET etc) and corresponding function/class/component does not strictly follow standards, then it may get sent and then you will have it as part of query string (but the web server may reject such request, although unlikely).
If URL is: /something.php?task=show#kitten, then #kitten is the hash (including the actual hash symbol #). The proper name of kitten here is Fragment Identifier.