IIS rewrite rule not working in live environment - regex

I have 4 servers in azure, 3 are load balanced and the 4th is for CMS purposes only.
SSL certificate has been added for the main website, but not for the sobdomain that the CMS is on.
I wrote a rule that should find any url that doesnt contain "backoffice" and match any other page to change it to https.
This works on regexr.com but for some reason doesnt work
<rewrite>
<rules>
<rule name="http to https" stopProcessing="true">
<match url="(https?:\/\/(?!backoffice).*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://www.WEBSITENAME.com{R:1}" />
</rule>
</rules>
</rewrite>
Url Rewriting 2.1 is installed on all 4 servers and i have created a load balance set in azure for https.
going to https manually works fine (along with loadbalancing).
Additional information:
I've tried many rules, including the existing answer. I can see things happening, like assets being brought in as https, but the page itself does not redirect.
There are 2 load balance sets, one for port 80 and the other for port 443. I don't know if this is corect, or could be a potential cause in the redirect not happening.

Your rule should be like that:
<rule name="http to https" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{REQUEST_URI}" pattern="/backoffice" negate="true" />
</conditions>
<action type="Redirect" url="https://www.WEBSITENAME.com{R:0}" />
</rule>
This rule will exclude requests with /backoffice path.
Also for issue of mixing content you need to fix your paths for css/js/images to relatives. Example:
<img src="/path/to/your/image.jpg"/>
Another way to fix mixed content is create outbound rule, which will change your output HTML (replace http: to https:):
<rewrite>
...
<outboundRules>
<rule name="Rewrite external references to use HTTPS" preCondition="IsHTML">
<match filterByTags="Script, Link, Img, CustomTags" customTags="HTML5Tags" pattern="^http://(.*)$" />
<action type="Rewrite" value="https://{R:1}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
<customTags>
<tags name="HTML5Tags">
<tag name="Video" attribute="src" />
</tags>
</customTags>
</outboundRules>
</rewrite>

Using the previous answer as a starting point, i made a few minor changes, to use HTTP_HOST rather than REQUEST_URI for the pattern negation and it works.
<system.webServer>
<rewrite xdt:Transform="InsertIfMissing">
<rules>
<rule name="http to https" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
<add input="{HTTP_HOST}" pattern="^backoffice\.WEBSITENAME\.com$" negate="true" />
</conditions>
<action type="Redirect" url="https://www.WEBSITENAME.com/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>

Related

IIS URL Rewrite for Laravel Application Not working for multiple URI Segments

I am having a scenario that if URL doesn't contain anything in URI segment then no need to rewrite to index.php but if contains then rewrite it.
For Example: http://www.example.com/ or http://www.example.com No Rewrite Rule Required
But if URL is http://www.example.com/homepage or http://www.example.com/user/1 or http://www.example.com/edit-user/123/456
then it should be rewrite to index.php
I tried below.
<rules>
<rule name="custom rule 1" stopProcessing="true">
<match url="^([^/]+)/?$" />
<action type="Rewrite" url="index.php" />
</rule>
It is working for http://www.example.com/ and http://www.example.com/homepage but showing 404 for others pages.
The URI segments are dynamic and it can be multilingual.
Technologies used IIS, PHP (Laravel)
You can try this, it will match all kinds of URIs whether dynamic or multilingual.
<rule name="custom rule">
<match url=".*" />
<action type="Rewrite" url="index.php" />
<conditions>
<add input="{REQUEST_URI}" pattern=".*" />
</conditions>
</rule>
Test result
Fail request tracing
If this rule is only used for some URIs like user or edit-user, maybe this rule is more suitable.
<rule name="custom rule">
<match url=".*" />
<action type="Rewrite" url="index.php" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_URI}" pattern="user/(.*)" />
<add input="{REQUEST_URI}" pattern="edit-user/(.*)" />
</conditions>
</rule>

Rule not working in rewrite rules despite valid regex

Our webconfig file uses Url Rewrite, essentially pushing any http traffic to https
This works fine other than developing locally. For a while we have to simply remember to comment out the code from the web.config and uncomment it again for commit. Naturally this isn't a good way to work.
The code is simple
<rewrite>
<rules>
<rule name="Redirect-AllWWW-ToSecureNonWWW">
<match url="^((?!local).)*$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^(?:www\.)(.+)$" />
</conditions>
<action type="Redirect" url="https://{C:1}/{R:0}"/>
</rule>
<rule name="Redirect-AllNonSecure-ToSecureNonWWW-ExcludingLocalhost">
<match url="^((?!local).)*$" />
<conditions>
<add input="{HTTP_HOST}" pattern="^localhost$" negate="true" />
<add input="{HTTPS}" pattern="^off$" />
<add input="{HTTP_HOST}" pattern="^(?:www\.)?(.+)" />
</conditions>
<action type="Redirect" url="https://{C:1}/{R:0}" />
</rule>
</rules>
</rewrite>
And as per the regex101 , it works!
https://regex101.com/r/3Mz6w1/1
However, when on localhost, I am still directed to HTTPS
Why does it work in regex101 and not in my web.config file
This seems to be related to Redirect rule not working
quote from URL Rewrite Module Configuration Reference
A rewrite rule pattern is used to specify a pattern to which the current URL path is compared.
...
A pattern is specified within a <match> element of a rewrite rule.
According to this piece of official information, you must be sure that <match url compares only with URL paths which never contain host names, not the entire URL.
For Url Rewrite Module, URL path of this question is questions/44944175/rule-not-working-in-rewrite-rules-despite-valid-regex for example. No stackoverflow.com no https:// no query strings but only the path without leading slash.
To ignore requests for host names containing local you need some conditions looking for a local match with HTTP_HOST header.
<rewrite>
<rules>
<rule name="Redirect-AllWWW-ToSecureNonWWW" stopProcessing="true">
<match url=".*" />
<conditions>
<!-- continue if http host name does not contain "local" -->
<add input="{HTTP_HOST}" pattern="local" negate="true" />
<add input="{HTTP_HOST}" pattern="^(?:www\.)(.+)$" />
</conditions>
<action type="Redirect" url="https://{C:1}/{R:0}" />
</rule>
<rule name="Redirect-AllNonSecure-ToSecureNonWWW-ExcludingLocalhost" stopProcessing="true">
<match url=".*" />
<conditions>
<!-- continue if http host name does not contain "local" -->
<add input="{HTTP_HOST}" pattern="local" negate="true" />
<add input="{HTTPS}" pattern="^off$" />
<add input="{HTTP_HOST}" pattern="^(?:www\.)?(.+)" />
</conditions>
<action type="Redirect" url="https://{C:1}/{R:0}" />
</rule>
</rules>
</rewrite>

Rewrite rule to HTTPS except when on localhost

I am using the answer given here as the basis for trying to add a rewrite rule to my web.config file. I want it to match any url that is not running on localhost in order to force https.
Here is what I have right now:
<system.webServer>
<rewrite> <!-- force https - https://stackoverflow.com/a/15119044/51 -->
<rules>
<rule name="Redirect HTTP to HTTPS" stopProcessing="true">
<match url="^((?!localhost).)*$"/>
<conditions>
<add input="{HTTPS}" pattern="^OFF$"/>
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther"/>
</rule>
</rules>
</rewrite>
</system.webServer>
I am trying to use a negative lookaround in order to only match url's that do not include "localhost" within the url. But this is not working.
So how should this rule be set up in order to only rewrite non-localhost url's?
Try this condition:
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect HTTP to HTTPS" stopProcessing="true">
<match url="^(.*)$"/>
<conditions>
<add input="{HTTPS}" pattern="^OFF$"/>
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^localhost$" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther"/>
</rule>
</rules>
</rewrite>
</system.webServer>
Using a negate condition against the localhost pattern should do the trick.
Adding to anubhava's answer, you can replace the add element for localhost with the following 2 entries to cater for both localhost and 127.0.0.1 with optional ports e.g localhost:59400 which is the case when debugging through visual studio and IIS
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^localhost(:\d+)?$" negate="true" />
<add input="{HTTP_HOST}" matchType="Pattern" pattern="^127\.0\.0\.1(:\d+)?$" negate="true" />
With the original answer, localhost:123 would be redirected to https which may not be desirable.
Regular expression updated, this works for me, with a custom Port
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{HTTP_HOST}" matchType="Pattern" pattern="(localhost)(:\d+)" negate="true" />
<add input="{HTTP_HOST}" matchType="Pattern" pattern="(127.0.0.1)(:\d+)" negate="true" />

IIS 7 Redirect using regular expression

We currently have a wordpress blog running under a sub domain http:// blog.domain.com. That site is also currently running via reverse proxy as http:// www.domain.com/blog that points to the original subdomain site.
Currently both sites are running correctly but the issue we have is that we want the sub domain site to redirect to the reversed proxy site and not render. We only want the site to render as http:// www.domain.com/blog. I have been attempting to use the URL Rewrite in IIS 7 on a server 2008 machine.
I think the issue I am having is with the regular expression. I tried using -- ^(blog.)* -- and when I test it in IIS it returns that it matches (blog.domainname.com) but the site itself does not redirect when I open it in a browser. I'm not sure what I am missing. Thanks in advance for your help.
<rewrite>
<rules>
<rule name="Main Rule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" /></rule>
<rule name="wordpress" patternSyntax="Wildcard">
<match url="*" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" /> </rule>
<rule name="redirect to /blog" enabled="false" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^(blog.)*" />
<action type="Redirect" url="http:// www.domainname.com/blog" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="(.*)" />
</conditions>
</rule>
</rules>
</rewrite>
The problem is probably that your rewrite rules are not running when you hit that URL.
Make sure that it's actually mapped to that site.
Sorry, I just noticed that your rule is not enabled:
<rule name="redirect to /blog" enabled="false" patternSyntax="ECMAScript" stopProcessing="true">
You'd have to modify the enabled attribute to True.

URL Rewrite - stop https for staging guid url on Azure (IIS)

I have this rewrite rule in web.config on our Azure app to ensure the users always use HTTPS:
<rule name="HTTP to HTTPS redirect"
stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}"
pattern="off" />
<add input="{REQUEST_URI}"
pattern="^clientaccesspolicy\.xml$"
negate="true" />
<add input="{REQUEST_URI}"
pattern="^crossdomain\.xml$"
negate="true" />
</conditions>
<action type="Redirect"
redirectType="Found"
url="https://{HTTP_HOST}/{R:1}" />
</rule>
It works fine. The users always hit the site using a subdomain of our company URL and we have a wildcard certificate.
But when the app is staging I would like to use it without https (but still not allow http acccess to the standard cloudapp subdomain).
so for example this would work over http:
http://f9eccd6a9a044270b5ce97ae614c9ee1.cloudapp.net
But this wouldn't:
http://myazuresubdomain.cloudapp.net
My Regex skills are minimal and my url rewrite skils are limited to copying the above from SO. So could someone help me with the rule that will help me acheive the above? Perhaps a negate for a url that has exactly 32 chracters then .cloudapp.net?
Thanks
Mark
The following rule should match what you're after. Placing it first will skip the https redirect due to the 'stopProcessing' attribute.
<rule name="Staging CloudApp" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="([0-9a-f]{32})\.cloudapp\.net" />
</conditions>
<action type="None" />
</rule>