IIS UrlRewriter Outbound rules ignored if PreCondition is set - iis-7

I have a very simple OutBound UrlRewriter rule that rewrites url's it finds in the body of the http response stream:
<rewrite>
<outboundRules>
<rule name="Scripted"
preCondition="IsHtml"
patternSyntax="ECMAScript"
stopProcessing="false">
<match filterByTags="None" pattern="http://someurl.com" />
<action type="Rewrite" value="http://anotherurl.com" />
</rule>
<preConditions>
<preCondition name="IsHtml" patternSyntax="Wildcard">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
The problem is that as soon as I turn on the preCondition no rewriting takes place.
I need to be able to use a pre-condition because the page is an ASP.NET page and uses ASP.NET script resources e.g. <script src="ScriptResource.axd?d=...." type="text/javascript" />.
By default script resources are gzip compressed and I want to keep them that way. Without the content type precondition the URL rewriter RewriteModule throws a 500.52 error - "Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("gzip")."
Using Fiddler I can see that Content-Type: text/html; charset=utf-8 is being sent in the response header but UrlRwriter seems unable to match this.
Why is this happening?

This is because the Server Variable HTTP_ACCEPT_ENCODING is not added to the allowed server variables list. Add it there (you can google how to in IIS).

Related

Webconfig inbound rule to avoid showing js files

I have created below rules
<rule name="block js files">
<match url=".*\.(js)/*$"/>
<action type="Redirect" url="http://{SERVER_NAME}/notfound/{R:1}" redirectType="notFound"/>
</rule>
This will move the request for js files to some not found page. and this is working correctly.
But when its also blocking the requested js files from the application.
I think the js files requested from the application lies under outbound rules.
So I want to put my above rules in inbound section as I believe request from browser lies under inbound rules.
What should I update here?
Thanks
I think you could whitelist your domain from HTTP_REFERER. So that either you access the js from external or access it directly, IIS will redirect the request. At the same time, IIS won't block request that referrered from your domain. Of course, you could enable CORS header.
Besides, "notFound" is not a vaild redirectType. Are you looking for "Found" instead of "notFound"?
<rule name="block js files" enabled="true" stopProcessing="true">
<match url=".*\.(js)/*$" />
<action type="Redirect" url="http://{SERVER_NAME}/notfound/{R:1}" redirectType="Found" />
<conditions>
<add input="{HTTP_REFERER}" pattern="mydomain.com" negate="true" />
</conditions>
</rule>

ASP.NET rewrite redirect url on IIS (for Facebook social login)

I have an application that is behind a reverse proxy and when the user is trying to log in with a Facebook account, it fails because the redirect uri is an internal uri, instead of the public domain.
To come around this I want to rewrite redirected url.
This is the flow:
User logs in to Facebook
Microsoft.AspNetCore.Authentication.Facebook nuget package takes over the authentication process
A redirection (302) GET request happens to this url:
https://www.facebook.com/v2.6/dialog/oauth?client_id={clientid}&scope=public_profile,email&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fsignin-facebook&state={longstring}
And this is the part that I want to rewrite:
redirect_uri=https%3A%2F%2Flocalhost%3A5000%2Fsignin-facebook to
redirect_uri=https://mypublicdomain.com/signin-facebook
Is this possible with IIS Url rewrite module?
I tried to configure it but couldn't get it to work.
(on the server I'm using ASP.NETCORE 1.1.2)
<outboundRules>
<remove name="Rewrite Location Header" />
<rule name="Rewrite Location Header" preCondition="IsRedirection" enabled="true">
<match serverVariable="RESPONSE_Location" pattern="^https:\/\/(.*&redirect_uri=)([^&]*)(.*)" />
<action type="Rewrite" value="{R:1}https://google.com{R:3}" replace="false" />
</rule>
<preConditions>
<preCondition name="IsRedirection">
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
Yes this is possible. Make sure to use the {QUERY_STRING} input to match against and ensure you have Rewrite as the action type.
A similar solution you could use as a starting point can be found here

Remove /index.aspx from resolved url

I'm trying to add an outbound rewrite rule that removed index.aspx from a resolved url on a website. See my below update for the rule I have in place. See second update as to my findings with regards to a simple rule not working.
In both scenarios I get a 500 error and can't see anything in Event Viewer to help narrow down the problem. We have inbound rules already that work fine so it's specifically an issue when I add an outbound rule.
UPDATE
I've been reading online and have tried with the following outbound rule but keep getting a 500 internal server error?
<outboundRules>
<rule name="Remove index.aspx" preCondition="IsHTML">
<match pattern="(.*?)/?index\.aspx" />
<action type="Rewrite" value="{R:1}/" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
UPDATE 2
I've noticed that this isn't a problem with the syntax of my outbound rule as even putting in the simplest of rules through the IIS interface breaks the website (causing a 500 error):
<outboundRules>
<rule name="test">
<match filterByTags="A" pattern="test.com" />
<action type="Rewrite" value="blah" />
</rule>
</outboundRules>
The URL rewrite module is installed as we have inbound rules that work correctly. The version of IIS is 7 if that helps.
Are you using GZIP compression? This conflicts with outbound rewrite rules and could be the cause of the error.
See: http://forums.iis.net/t/1165899.aspx for some advice on how to combine outbound redirect rules with compression.

Enabling CORS for website on Azure CDN to host fonts

I have an Azure Website (Asp.net MVC) that includes fonts (font-awesome, glyphicons for example) and is availale at a custom domain, let's say www.mywebsite.com.
I have also setup an Azure CDN with the origin host pointing to the website (not to a blob storage). In addition, I'm using a custom domain name for the cdn, like "cdn.mywebsite.com".
The problem I'm having is that browsers are refusing to download the fonts because CORS is not enabled. I've found ways to enable CORS on Azure blob storage but I would really prefer to get this work just by pointing the CDN to the Website.
Any ideas on how this could be done?
Assuming you have some basic CDN rewrite rules in your web.config system.webserver section, you may also add some outbound rules to enable CORS for CDN requests...
<rewrite>
<outboundRules>
<rule name="Set Access-Control-Allow-Origin Header" preCondition="Origin header present">
<match serverVariable="RESPONSE_Access-Control-Allow-Origin" pattern="(.*)" />
<action type="Rewrite" value="*" />
</rule>
<preConditions>
<preCondition name="Origin header present" logicalGrouping="MatchAll">
<add input="{HTTP_ORIGIN}" pattern="(.+)" />
<add input="{HTTP_X_ORIGINAL_URL}" pattern="^/cdn/(.*)$" />
</preCondition>
</preConditions>
</outboundRules>
<rules>
<rule name="Rewrite CDN" stopProcessing="true">
<match url="^cdn/(.*)$" />
<action type="Rewrite" url="{R:1}" />
</rule>
</rules>
</rewrite>
This outbound rule adds Access-Control-Allow-Origin: * response header to every request through Azure CDN that contains non empty Origin: request header.

HTTP Error 500.52 - URL Rewrite Module Error.

I am trying to setup a reverse proxy with IIS 7.5. I want an incoming request that matches a certain URL pattern to be served by Tomcat. I have used the tutorial here to configure it.
http://www.iis.net/learn/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing
My settings are as below:
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url=".*/(Locations|FacetedSearch|LocationPage)/.*" />
<action type="Rewrite" url="http://search.xxx.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" replace="true" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://search.xxx.com/(.*)" />
<action type="Rewrite" value="http{R:1}://dev.xxx.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<tracing>
HTTP Error 500.52 - URL Rewrite Module Error.
Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("deflate").
I just hit this issue as well, and I found this solution helpful: https://www.saotn.org/iis-outbound-rules-with-gzip-compression/
Basically, on inbound requests the HTTP_ACCEPT_ENCODING header gets stashed into a temporary header, and then gets restored back on the outbound rewrite rule.
In the case the link goes dead, here's the steps:
Through the IIS Manager GUI on the server node in the left pane, navigate to URL Rewrite
Click View Server Variables in the right pane
Add two Allowed Server Variables:
HTTP_ACCEPT_ENCODING
HTTP_X_ORIGINAL_ACCEPT_ENCODING
Back in URL Rewrite options for the Server, click on View Preconditions in the right pane. Add a new precondition (I named it NeedsRestoringAcceptEncoding)
Set the Condition Input to {HTTP_X_ORIGINAL_ACCEPT_ENCODING} and the Pattern to ".+" (no quotes).
On the inbound rewrite rule that is causing the error, add the following to Server Variables (you'll find it underneath the Conditions section):
Server Variable Name: HTTP_X_ORIGINAL_ACCEPT_ENCODING
Value: {HTTP_ACCEPT_ENCODING}
Server Variable Name: HTTP_ACCEPT_ENCODING
Value: ""
On the outbound rewrite rule, add the precondition created from steps 4-5 to the Precondition section of the rule (it should be populated in the drop-down box)
In the case that you only need this functionality on a single site, you can add the precondition at the site-level instead of the server-level.
Add this to your web config
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
or disable dynamic compression in iis
find "compress" in IIS,then remove the dynamic content compression and static content compression.
Disabling dynamic and static content compression from the site responsible for reverse proxying the requests AND the site that is being proxied fixed this error for me.
To put it in other words - if server X is routing requests to server Y, then disable dynamic and static content compression on the sites on both server X and Y.

Resources