IIS URL rewrite from one site to another applies custom headers from the web.config of both sites - web-config

I have two sites set up in IIS 8.5, which I'll call test 1 (test1.mydomain.com) and test 2 (test2.mydomain.com).
There is a URL rewrite rule in the test 1 web.config which rewrites test1.mydomain.com/app/{route} as test2.mydomain.com/{route}.
<rule name="Test 2 rewrite" stopProcessing="false">
<match url="^app(\/.*)?$" />
<action type="Rewrite" url="https://test2.mydomain.com{R:1}" />
</rule>
This is all working as expected, however I've found that when this rewrite rule is applied, the custom headers in the test 1 web.config are being included alongside the custom headers in the test 2 web.config. More specifically, this means I have two content security policy headers in the response.
This is causing issues, because test 1 has a stricter policy than test 2, so when accessing test1.mydomain.com/app, scripts and styles are failing to load.
I've tried wrapping the system.web and system.webServer for test 1 with a location tag, to see if I could prevent them from being inherited, but this has no effect:
<location path="." inheritInChildApplications="false">
<system.web>
...
</system.web>
<system.webServer>
...
</system.webServer>
</location>
When the url is rewritten to point to test 2, I only want the test 2 web.config to apply to that request. Is this even possible? If it's not possible, is the only solution to extend the CSP of site 1 to meet the requirements of site 2?
Thanks.

You have to use <action type="Redirect", not the <action type="Rewrite":
<action type="Redirect" url="https://test2.mydomain.com{R:1}" />

Related

IIS URL rewrite - reverse proxy - responding with 404 error

basically i wanna to rewrite url using reverse proxy:
from:
http://www.xyz.in/eacc/api/fetchVendors
to
http://localhost:8080/eacc/api/fetchVendors
I have deployed my spring boot rest full web service application in tomcat under C:\Tomcat\apache-tomcat-9.0.7\webapps\eacc.
It contains many POST call like /eacc/api/fetchVendors, /eacc/api/users, /eacc/api/clients.. etc.
Now i wanna to expose this eacc rest application through IIS.
have main website configured called www.xyz.in.
added virtual directory under website (www.xyz.in) called /eacc.
physical path: C:\inetpub\wwwroot\eacc
below is web.config file.
When i try to hit one post call like www.xyz.in/eacc/api/fetchVendors, getting HTTP 404 server error.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /eacc/api/fetchVendors
My web.config file for /eacc - virtual directory
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpRedirect enabled="false" />
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:8080/eacc/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:8080/eacc/(.*)" />
<action type="Rewrite" value="http{R:1}://www.xyz.in/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Am new to IIS web server.have stuck with URL Rewrite reverse proxy pattern. have tried many pattern changes but no luck. Looking help from anyone.
For me, this worked on IIS:
Go to IIS root node >> ARR
Click "Server Proxy Settings" option
and enable it:
Inbound Rule:
Use Patters : ^eacc.*
Rewrite URL : http://localhost:8080/{R:0}
Outbound Rule:
Pattern : localhost:8080
Value : www.xyz.com
Also you need to Add Proxy settings (Application Request Routing Module - Server Proxy settings) :
(tick) Enable Proxy
(untick) REverse Rewrite in response headers

Need to get a site redirecting both to www and https

Parts of other answers on Stack Overflow worked, other parts didn't, so I thought I would ask for the full solution including IIS settings re bindings.
I have a site (old ASP classic) that is being moved to IIS 8 (2012).
The site works when testing it from my hosts file.
At the moment I can only get it to redirect http to https not non www requests to www.example.com as well.
So I have 2 bindings in IIS (80/433) for www.example.com, I also tried it with another set without the www. e.g example.com but then I got errors such as the system is trying to process your request in such a way it won't return e.g following redirects around in a circle etc.
I am not so sure if that was about the 2 lots of bindings or the rules it was getting a bit messy then. So I need the whole approach from IIS binding setup and web.config rules (or is there a better way in IIS 8 to force all 80 traffic to port 443?)
I already have a number of ISAPI rules in my web.config file such as
<rule name="Order" stopProcessing="false">
<match url="^applications/order/?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="plugins/order.asp" />
</rule>
<rule name="Robots 1" stopProcessing="false">
<match url="^robotstxt\.asp$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="robottxt.asp" />
</rule>
<rule name="Robots 2" stopProcessing="false">
<match url="^robotstxt$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="robottxt.asp" />
</rule>
So when I read up I saw about people trying to to do both rules at once or in two sets but it just never managed to work foe me.
I need non http requests to go to https
and for non www requests to go to www.example.com e.g https://www.example.com
At the moment it's partially working but only because I am not trying the non www. redirects.
I have 2 bindings for the www.example.com hostnames and this one rule at the top.
<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
</rule>
So all the rules are working including the http to https. However I need non www rules to work as well.
To get it to keep the rest of my rules AND to get it to ALSO redirect non www. traffic to www.example.com e.g https://www.example.com. What is the best way to do this.
Do I need another pair of bindings set up without www. e.s example.com for 80/443?
Then, what rules do I add in and what order do they need to be as int .htacces they are processed top to bottom in loops an I just wonder with IIS way there is also a logical path that could trip it over causing infinite loops.
I think adding the include is what I would do if you needed to get on top of this very quickly. Use a search and replace program to add the include tag into all of your pages:
<!--#include file="redirect.asp"-->
Then create the "redirect.asp" with something similar to below:
<%
webDomain=LCase(Request.ServerVariables("HTTP_HOST"))
scriptname=Request.ServerVariables("SCRIPT_NAME")
If InStr(webDomain,"https://www.example.com")=0 Then
Response.Status="301 Moved Permanently"
Response.AddHeader "Location", "https://www.example.com" & scriptname
End If
%>
You may need to tweak that a bit but its the basics of a coded redirect anyway.

Creating a IIS Url Rewrite/Redirect

Im struggling to get a url rewrite/redirect to work in IIS. I've installed the url rewrite module and all the rules fail to do anything. Here is the scenario, we want all web requests which generate a report to be pushed off to a secondary server so it doesn't harm the main box. The web requests that generate reports look something like this:
http://mywebaddress/api/Actionname=GenerateReport&param=123
So im wanting to do some type of regex check on finding any web requests that have "GenerateReport" in it and redirect it to something like:
http://mywebaddressofsecondserver/api/Actionname=GenerateReport&param=123
Any ideas on how the redirect/rewrite would go for this?
You need to check if REQUEST_URI contains Actionname=GenerateReport.
If so, you'll redirect it to other webserver url equivalent.
Translated to an IIS rewrite rule, it would look like this
<rule name="Delegate report generation" stopProcessing="true">
<match url="^(.*)$" />
<conditions>
<add input="{REQUEST_URI}" pattern="Actionname=GenerateReport" />
</conditions>
<action type="Redirect" url="http://mywebaddressofsecondserver/{R:1}" />
</rule>
Thanks, Justin Iurman,
Your answer solved my issue of getting methods
http://mywebaddress/api/Param/Action1
http://localserverwithport/api/Param/Action1
but for below Post methods it's still giving 404 not found
http://mywebaddress/api/Param/PostAction2
http://localserverwithport/api/Param/PostAction2
Post parameters are:
{"Param1":"James","Param2":"jani"}
My implementation is
'<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite Rule1" >
<match url="^(.*)" />
<action type="Redirect" url="http://localserverwithport/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>'

Rewrite Maps in IIS7 - Not redirecting

I'm trying to use a separate config file, named "rewritemaps.config", that contains the URLs I want to redirect. The file is in the root directory (same place as the web.config). The format of the Redirects.config file I have is:
<rewriteMaps>
<rewriteMap name="Redirects">
<add key="aspx/drvmain.aspx"
value="http://www.newdomain.com/folder2/page2.aspx" />
<add key="aspx/jobs_AboutUs.aspx"
value="http://www.newdomain.com/folder1/jobs.aspx" />
<add key="aspx/page.aspx"
value="http://www.newdomain.com/folder1/page2.aspx" />
</rewriteMap>
</rewriteMaps>
In my web.config file, I have:
<system.webServer>
<rewrite>
<rewriteMaps configSource="rewritemaps.config" />
<rules>
<rule name="Redirect rules">
<match url=".*" />
<conditions>
<add input="{Redirects:{REQUEST_URI}}" pattern="(.+)" />
</conditions>
<action type="Redirect" redirectType="Permanent"
url="{C:1}" appendQueryString="false" />
</rule>
</rules>
</rewriteMaps>
</rewrite>
</system.webServer>
In the IIS Manager (which, yes, I have installed the URL Rewrite module), I've even gone and tested the rule and condition against one of my URLs in the redirects.config file and it says it works. But then when I try going to the URL in my browser, it doesn't redirect as I've specified. In the rewritemaps.config file, I've tried putting the full domain, and I've tried with a "/" before aspx. Nothing seems to work. I'm not sure what I'm missing here.
Well I got it working. Was something stupid. In the rewritemaps.config file, I needed "/"s before the key URL. I know I had tried that before, but I must have been missing something somewhere else at the time. Oh well. It works now.
It is really hard to determine why this is failing but the best thing you can do is use Failed Request Tracing so that IIS tells you what is happening. With FREB you will get detailed tracing telling you which rules were evaluated and if they matched or they didn't and why not. You can also see the "right" patterns to match and every condition that is evaluated.
See the following link:
http://www.iis.net/learn/extensions/url-rewrite-module/using-failed-request-tracing-to-trace-rewrite-rules

Advanced ASP.NET MVC routing scenario

I have an ASP.NET MVC app with the following deployment requirements:
The URL structure must be something like:
http://server/app/[enterprise]/[communinty]/{controller}/{action}/...
What I think I want to be able to do is intercept the URL before the MVC route handler gets its hands on it, remove the [enterprise]/[community] parts, and then allow MVC to continue processing as if the original URL had not contained those two segments.
Here's why:
The application exposes multiple portals to multiple customers (enterprises), and each community within an enterprise has its own user population. This kind of scheme could also be served by physically deploying one application instance (binaries,content,web.config) into each [community] directory, but for logistical and performance reasons, I don't think we want to go down this path. So I'm trying to virtualize it through routing tricks.
Any suggestions on how to go about this scheme, or alternate solutions would be appreciated.
We are on IIS 7, if that makes any difference.
You can use the following route before the default route
routes.MapRoute(
null,
"{enterprise}/{community}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
You can then ignore {enterprise} and {community} parameters in your action methods.
Here is a possible solution with IIS Rewrite module. It may not be the best approach, but it may work. Is there an easier/better option within the MVC routing? Not sure. Only just started doing that myself.
Using "http://server.com/app/enterprise/community/controller/action/" as an example.
What happens:
Strips the string out of the URL. New
URL:
http://server.com/controller/action/
Redirects the user to new URL. User's
browser now shows:
http://server.com/controller/action/
Takes the new URL and tries to
rebuild it to grab the correct
content. User's browser shows:
http://server.com/controller/action/ ;
IIS returns:
http://server.com/app/enterprise/community/controller/action/
All of this would be in the web.config once the IIS rewrite module is installed:
<rewrite>
<rules>
<clear />
<rule name="Redirect to remove Offending String" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="server.com/app/enterprise/community*" />
<action type="Redirect" url="/{R:1}" />
<conditions logicalGrouping="MatchAll">
<add input="{SERVER_NAME}" pattern="*server.com*" />
</conditions>
</rule>
<rule name="Rewrite to get Original Content" enabled="true" patternSyntax="Wildcard" stopProcessing="false">
<match url="*" />
<conditions logicalGrouping="MatchAll">
<add input="{SERVER_NAME}" pattern="*server.com*" />
</conditions>
<action type="Rewrite" url="app/enterprise/community{R:1}" />
</rule>
</rules>
</rewrite>
Note: Just did this quick, haven't tested.