Problem with URL rewrite on IIS 7.5 - iis

I'm trying to use the URL Rewrite module for IIS 7.5 to redirect all HTTP requests to HTTPS for my ASP.NET website. The site works fine at the moment but forces the user to type the https:// in the address bar.
I followed the instructions in this article. Everything seems to be fine: I've tried putting the rule in the web.config and it shows up in the UI as it should; I've also done the reverse and can see the changes in the web.config when I use the UI to add the rule. I have RequireSSL unchecked for the site. Unfortunately I still just get a 404 when I try to hit the site via http://.
I've tried a few different action urls including {HTTP_HOST}/{R:1} and the one shown below.. nothing works.
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect to https" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}"
redirectType="SeeOther" />
</rule>
</rules>
</rewrite>
</system.webServer>
I'm fairly new to this and pretty frustrated at this point. Seems like this should be a lot easier. Any advice would be appreciated, thanks..
Reposting from ServerFault as it's been sitting unanswered for a while.

HTTP Error 404. The requested resource is not found
Do you actually have binding for HTTP 80 port? Sounds like you do not have it (only HTTPS).
The reason I'm asking is the quoted text is the exact message that I would see if I request unknown to IIS domain (when there is no catch-all defined) or domain is not bound to the requested port.

Related

IIS URL rewriting has trouble with subcalls

I have two virtual machines. The first one (VM1) is running a web application with an URL like this:
VM1/servicedesk/customer/user/login
The second (VM2) should now redirect to this address without changing the URL and also doesn't allow to redirect to the root / since that is a different web-application. This works relatively easily with this rewrite rule:
<rule name="rewriteAll" stopProcessing="true">
<match url=".*" />
<action type="Rewrite" url="http://VM1/servicedesk/customer/user/login" />
</rule>
It just basically rewrites everything from VM2 to the specific VM1 URL.
The problem I'm facing is that this web-application has many Ajax calls to other addresses on the same VM1.
For example VM1/rest/... or VM1/s/.... I really tried to find each exceptional call and create a rule before this default Rewrite. But since some of them are nested and could be changed this isn't a good approach. So what i need is basically a rewrite without changing the URL what doesn't break the application that does a lot of nested calls.
I found out that i can use the following rule (redirectRest) before the existing rewriteAll rule to redirect subcalls (VM1/rest/..).
<rule name="redirectRest" stopProcessing="true">
<match url="/.*" />
<action type="Redirect" url="http://VM1/{R:0}" />
</rule>
<rule name="rewriteAll" stopProcessing="true">
<match url=".*" />
<action type="Rewrite" url="http://VM1/servicedesk/customer/user/login" />
</rule>
So basically when I call VM1 the second rule applies and I get rewritten to the web-app. The application hosted there will call e.g. VM1/rest what triggers the first rule and redirect the Ajax calls to the root. But I've found out that Ajax calls are not following a redirect like 301.

Redirect to FQDN in IIS Not Working

None of the answers I've found to questions like this (notably this one) work for me, so here I go.
We are running IIS 8 on Windows Server 2012 R2. We have a wildcard certificate (*.mydomain.com) installed on the server. On the Default Web Site we have a single binding to accept incoming https requests on port 443. I have a second Web Site set with a single binding to accept incoming http requests on port 80.
On the latter Web Site I've created a URL Rewrite rule to redirect all incoming non-HTTP traffic to https://myserver.mydomain.com{REQUEST_URI}, and this works perfectly. If I browse to either http://myserver.mydomain.com/homepage or http://myserver/homepage, I am sucessfully redirected to the HTTPS version of the site with the full domain name included and thus it loads just fine.
If I browse to https://myserver.mydomain.com/homepage, the site also loads perfectly.
However, I am trying to create another URL Rewrite rule on the Default Web Site so that requests to https://myserver/homepage (Note: HTTPS but the full domain name is omitted) are redirected to the https://myserver.mydomain.com/homepage. The reason for this is that the SSL certificate is only matched if the full domain is included. As it stands, if I enter https://myserver/homepage I get a security warning (NET::ERR_CERT_COMMON_NAME_INVALID).
I've created the rule which I think should work, based on the answer I linked to above, but it doesn't work and I don't know why. My rule look like this:
<rewrite>
<rules>
<rule name="Redirect to FQDN" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^myserver$" />
<add input="{HTTPS}" pattern="^ON$" />
</conditions>
<action type="Rewrite" url="https://myserver.mydomain.com/{R:1}" />
</rule>
</rules>
</rewrite>
Even with this rule in place and enabled, when I browse to https://myserver/homepage I get the security message. What am I doing wrong with this rule?
Problem is that you have SSL only for *.mydomain.com. And when you accessing https://myserver it will return certificate error because your cert is not valid for this domain.
For better understanding about steps during SSL connection:
In your case, the problem is between step 2 and 3

Azure App Service Always On with custom domain redirect not hitting default web page

Azure App Service AlwaysOn works perfectly once there is no custom domain set for the web application. Once custom domain is added along with URL rewrite rule to redirect all incoming request to it, application starts to response slowly after some time of inactivity. Logs show that AlwaysOn still pings azure domain and gets HTTP 301 response ans is not trying to request new URL.
Log without custom domain:
2017-06-20 17:17:02 ZZTESTSITE GET / X-ARR-LOG-ID=743965b6-d3e2-42b9-9353-7772f9fbc898 80 - ::1 AlwaysOn ARRAffinity=b5289afa9cd711b67c1fe9137a6e3ff232f80bd3fa1bd96e9fc89992472b4e57 - zztestsite.azurewebsites.net 200 0 0 11433 652 15
Log with custom domain
2017-06-21 13:28:52 ZZTESTSITE GET / X-ARR-LOG-ID=ffcd5992-5019-48ca-a386-76443a8c7226 80 - ::1 AlwaysOn ARRAffinity=b5289afa9cd711b67c1fe9137a6e3ff232f80bd3fa1bd96e9fc89992472b4e57 - zztestsite.azurewebsites.net 301 0 0 553 652 46
URL Rewrite rule:
<rule name="Redirect requests from default azure websites domain to custom one" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^zztestsite\.azurewebsites\.net$" />
</conditions>
<action type="Redirect" url="http://mycustomdomain.com" redirectType="Permanent" appendQueryString="false"/>
</rule>
Additionally once SSL in enabled and another rule is added to redirect all requests to HTTPS, same issue will arise.
How can I tackle this problem? I found two possible directions:
Push AlwaysOn to ping custom domain (possibly https as an option)
Change URL Rewrite rule to one allowing AlwaysOn to ping azure domain, but all other shall be redirected
Please advise.
Try adding this line to your conditions:
<conditions>
<add input="{HTTP_HOST}" pattern="^zztestsite\.azurewebsites\.net$" />
<add input="{WARMUP_REQUEST}" pattern="1" negate="true" />
</conditions>
This tells is not to redirect for the Always On pings. Also note that I removed the MatchAny, as you really want MatchAll here (irrelevant when you only had one).
See here for a more complete example. It's for redirecting http to https, but the core idea is the same with respect to Always On requests. That example is an xdt transform, so it looks a bit different from 'straight' config. In fact you might consider using such xdt instead of polluting your web.config.
Finally I found the rule which works
<rule name="AlwaysOn agent requests without any redirections" stopProcessing="true">
<match url="^$"/>
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="^AlwaysOn$" />
</conditions>
<action type="None" />
</rule>
I put it as a first rule. Then other rules follow like "azure domain to custom domain redirect" and "HTTP to HTTPS".
David's answer was helpful however solves a bit different issue.

Redirect visitors to the canonical URL for a page using IIS

I want to ensure that anybody who goes to http://example.com/* gets automatically redirected to http://www.example.com/*. Currently, IIS allows either URL form to work, meaning that any page can be accessed at multiple URLs, which has a number of disadvantages (SEO, etc).
Is there any way to do this built into IIS (especially IIS 6) without setting up a third-party rewriting engine like this? It seems like a bazooka to kill a mosquito.
The easy way would be to simply remove the DNS entries for 'www.mysite.com', so the only DNS entries that exist are for 'mysite.com'.
Alternatively, here's a couple of techiques for redirecting to a canonical URI:
http://www.kalyani.com/2010/01/redirecting-to-canonical-url-in-iis7/
https://web.archive.org/web/20211020203216/https://www.4guysfromrolla.com/articles/072810-1.aspx
http://www.stevenhargrove.com/redirect-web-pages/
Basically you want to hand back a 301 Moved Permanently status for the non-canonical URIs, along with the canonical URI so the user agent may load it instead.
I have another solution for you:
<rule name="Canonical domain name" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>

How can I indicate to users that my IIS website is undergoing maintenance?

For my IIS website, I'd like to redirect ALL requests to ONE page. The purpose of this is that I want to do some maintenance on the database (take it off-line) that all my web applications use. I have about 50 web apps running under this website, so I'd like to avoid visiting each of them to change something. I'm thinking I could make a single change in machine.config? Any hints would be appreciated.
If you are using ASP.NET 2.0 (or higher), you can drop an app_offline.htm page on the root.
More info here.
in webconfig
<rewrite>
<rules>
<rule name="redirect all requests" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="index.php" appendQueryString="true" />
</rule>
</rules>
</rewrite>
Make all the pages un-available, probably stop the current web site and create an entire new completly blank site in its place. Then put up a custom error page for the 404 (file ot found) error. Custom Errors is a tab on the properties dialog of the web site in IIS. Just create the page you want to send, then change the entry for 404 on the custom errors tab to point to the new file you just created.
In IIS 10 there is an optional component "HTTP Redirect" (it may be available in earlier IIS versions; I don't know).
It allows you to set up very simple catch-all redirects, using any of the common HTTP redirect response codes.
This can be installed via Server Manager, in Windows Server 2019.
Could you create a new site in IIS with a binding to port 80 with a blank host-header (much like the Default site) and then stop the other site(s)? That way all requests would be handled by the new site, which could simply be a static HTML page notifying users that the site is down for maintenance.

Resources