Proxy - ASP.NET with or without MVC - proxy

I'm working on one multi-tenancy application, where each tenant will have access to 1 or more "sub applications" (different ASP.NET MVC websites).
http://v1.app1.domain.com
http://v1.app2.domain.com
http://v1.app3.domain.com
Later in time, I'll have new versions for each sub application and I will end with:
http://v1.app1.domain.com
http://v2.app1.domain.com
http://v3.app1.domain.com
http://v1.app2.domain.com
http://v2.app2.domain.com
http://v1.app3.domain.com
Some tenants will want to have access to the latest versions, and some will still be using old ones.
This is what I've done.
Now I would like to keep "the subdomain versions" hidden for them. They will only access the domain: app1.domain.com
This "internal smart proxy" will have the core to know which version this tenant has access.
Anyone knows how I can do this? In a way that all my internal urls (links, images, JS, css, etc...), AJAX,etc, will work correcly?
Or point me to some tutorials/blog/forums where i can find that can help me?
Thank you very much.

What you are trying to build is in essence an HTTP proxy. The difference to most other proxies is just that the actual URL is built on the server side.
There many different ways to do this. I'd choose one of the following:
Create an HTTP handler, in which case you could use this code project article as a starting point.
Use ASP.NET MVC. Create a "catch all" route and pipe that through one single action method.
Either way, you will have to
Analyze the HttpContext.Current.Request object and build a suitable outgoing URL
Use a HttpWebRequest to fetch the data from the actual website. Remember to mimic the original request header plus request content (usually POST parameters) if applicable.
Output the Response Header from the server and then output the data you just fetched.

Application Request Routing (ARR) could be a workable solution if you are using IIS 7 or 7.5.
You would have an additional web site defined in IIS acting as the proxy, which would be separate to the web site(s) your application uses.
The rules about which tenant is on which version would have to be written to a web.config for ARR to read. Is this acceptable? If you have a small number of tenants changing infrequently, you may be happy to edit this file by hand. If you need more automation, you could programatically generate this web.config file. Because this web.config is only for your ARR proxy site, editing it will not cause your application sites to restart.
A sample configuration might use the following IIS Sites:
proxy - binding for your public IP address. *.domain.com resolves to this address
v1app - binding for 127.0.0.101
v2app - binding for 127.0.0.102
IIS server-level settings: ARR cache -> Server Proxy Settings -> enable proxy. (Set the timeout here if your app needs long timeouts.)
And in your "proxy" site's web.config, the following rewrite rules:
<rewrite>
<rules>
<rule name="V1 tenants" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.101/{R:1}" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="app1.domain.com" />
<add input="{HTTP_HOST}" pattern="app3.domain.com" />
</conditions>
</rule>
<rule name="V2 tenants" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.102/{R:1}" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="app2.domain.com" />
</conditions>
</rule>
</rules>
</rewrite>
When a request comes in, it will hit your proxy site, then those rules will look at the hostname and redirect to the appropriate internal site.
If your ARR site is running on the same server as your content sites, you may want to remove the line
<add name="ApplicationRequestRouting" />
from C:\windows\system32\inetsrv\config\applicationHost.config, and add it as a module in your proxy site's web.config. This will apply ARR only to your proxy site, instead of the whole server.

Related

How to 'cloak' or 'rename' page name/location/url for user but still allow external site to correctly read the true url via HTTP_REFERER

My website has a partnership with external sites for members that allows access. The only way our members can access the external site is first if they are authenticated on our site, and then if they visit the external site from a specific page. Such as:
Our partner/external site checks HTTP_REFERER and verifies that the user is coming from the exact URL above and then allows them access.
So, we are stuck with this URL unless we request the partner change the URL on their side as well, which is a long complicated process.
I would like to make this URL prettier, but allow the external site to view the correct or "true" URL when the do an HTTP_REFERER so that they can still allow access for authenticated users from our site.
Some notes on my specific situation:
I am running pages on an IIS 7 Server.
Pages are .asp pages and utilizing Classic ASP VB server-side language.
I do not have access
to change anything on the external server checking the HTTP_REFERER
location.
I have tried doing:
<% Server.Transfer("/mynewpage/") %>
and that works in the sense that it makes the URL prettier while keeping the page at the same location. But the external site also reads the page as coming from "www.example.org/mynewpage/", which "breaks" our authentication because it's not the predefined page they are looking for to check authentication.
Is there another way that I can "cloak" or "rename" my URL to make it prettier, while still allowing the external site to correctly read the "True" URL when they do an HTTP_REFERER?
If your host has the URL rewrite module installed (which they probably will) then you can put rewrite rules into the system.webserver section of web.config eg
<rewrite>
<rules>
<rule name="ArticleDetail" stopProcessing="true">
<match url="^article/([^/]+)/?$"/>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="article.asp?id={R:1}"/>
</rule>
<rule name="Articles" stopProcessing="true">
<match url="^articles$"/>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
</conditions>
<action type="Rewrite" url="articles.asp"/>
</rule>
</rules>
</rewrite>
This is for standard master/detail pages called articles.asp and article.asp. yoururl/articles will find articles.asp and yoururl/article/30 will find articles.asp?id=30
The alternative is to set up a custom 404 page and use server.transfer in that. You would also use web.config to define your 404 page, but the rewrite engine is easier IMO. Using either approach, both the "pretty" URL and the original url would find the page.
Note that if you have IIS installed on your own machine you can use the Rewrite rule creator in that. When you use it you'll find that it's added the rules it created to web.config

keep URL same and load content of different website

I have first.abc.com/xyz (xyz being an application under main domain abc.com) that needs to load content off of a different website second.abc.com/whatever/xyz while keeping the URL same to first.abc.com/xyz how is this possible? I have looked into a couple videos for reverseproxy with ARR, but I am not an expert on servers. Hope I am clear on the issue at hand. Any help would be great.
you need to install
IIS URL rewrite module
IIS ARR routing for reverse proxy using
then add the routing in web.config ,or add in the applicationhost.config
here is the example
<rule name="ReverseProxy" enabled="true" stopProcessing="true">
<match url="(xyz)$" />
<action type="Rewrite" url="http://first.abc.com/xyz" appendQueryString="false" logRewrittenUrl="true" />
</rule>

Odd 404 during URL rewrite

Background: I'm forwarding incoming 80/443 traffic to \\SERVER2; TFS is running on \\SERVER3. I wish to route all TFS-related requests to \\SERVER3. I have to do it this way as I'm running Server Essentials on \\SERVER2, which is finicky enough to not work well under URL rewriting (almost as bad as SharePoint, but not quite).
Here's the only rule on the default website:
<rule name="TFS Rewrite" stopProcessing="true">
<match url="^tfs(.*)" />
<action type="Rewrite" url="http://server3:8080/{R:0}" />
</rule>
...and here's the Failed Request Log: https://1drv.ms/f/s!AodXF_j3BiWkhPAZwjnwC-rAecVgtw
Note the requested URL on line #87 of the PDF: http://server3:8080/tfs. I can browse to that internally just fine. The external URL is https://tfs.domain.com/tfs.
The next entry that's at all file-specific is the 404 itself, on line #165.
I just don't get this. It's a simple rule. Why would IIS turn up a 404 for a clearly valid and working URL?
EDIT
As a test, I added this condition:
<conditions>
<add input="{HTTP_HOST}" pattern="tfs.domain.com" />
</conditions>
Now if I browse to https://tfs.domain.com/, the default website loads.
This—together with the logs—would seem to indicate that while IIS is rewriting the URL, traffic isn't actually being routed to \\SERVER3.
What's going on here? This is a mystery.
OK, I got it working.
I'd installed both the URL Rewrite and ARR Modules, but I hadn't yet enabled proxy processing.
I created a dummy Reverse Proxy rule and was prompted to turn it on in IIS. I did so, deleted the dummy rule and now all is working as expected.

Does Crystal Reports support secure (HTTPS) images

You can enter a URL in a Crystal Reports image Graphic Location field to allow Crystal to load it dynamically at runtime. Eg: http://reports.server.com/logo.png or {?_pUrl} & "/logo.png"
Are you able to use a secure / HTTPS URL? Eg: https://reports.server.com/logo.png
I've verified outgoing HTTP connections using the TCP/IP tab of Process Explorer, but can't see any outgoing connections when using HTTPS.
My actual report is passing the base URL in via a parameter and works in an HTTP only environment. Also tried using a hard coded HTTPS url, to no avail.
I'm using version 14.0.2.364 RTM hosted in IIS on a 2012 R2 server.
Looks like Crystal Report 14.0.X (and earlier) does not support HTTPS Graphic Location - official reference from 2013.16.01.
Also checkout this thread (from 2013.Feb) where it's mentioned again Graphic Location formula over HTTPS is not supported.
Unfortunately it seems the issue is still not resolved.
The common suggested workarounds in the SAP's threads are:
using HTTP instead of HTTPS
having the image loaded locally (or from shared location)
use 3rd party tools to pre-download and store the image from the https to another (local) secure location.
It's not supported.
A SAP employee confirms this in this thread in the SAP community network (though it relates to an older version):
You're using the "Graphic Location" formula to specify a URL for the
image. When you return a string with http://, it's working, but not
with https://.
That's currently the behavior in Crystal Reports 2008 Designer, and
CR4E CRJ SDK reflects that behavior. [...] it's likely not something that would be implemented in CR4E in
the near future.
This also seems to be the case in CR2011 (14.0.x), as stated in another thread:
if the URL is secured one eg. HTTPS then crystal report wont be able
to process the images. Because HTTPS graphic location is not
supported.
A list of possible work-arounds to this problem:
Use HTTP rather than HTTPS (you may need to whitelist a particular URL or route if you require all access to be via HTTPS)
Pass the image via a binary field in your query (either by pushing it in via a dataset or by pulling it from your database)
Load images from a local filesystem
in Web.config, create a rule in the URL Rewrite, to exclude the file that generates the image, like this:
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{REQUEST_URI}" matchType="Pattern" pattern="\bBarcode.ashx\b" ignoreCase="true" negate="true" /> <!-- Crystal não suporta imagens https.. Criando exceção para imagens de barcode, utilizadas no crystal -->
</conditions>
<action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>

How do you properly install an ASP.NET MVC app as a child of another MVC app?

I have a main website app written in ASP.NET's MVC 3. Now, what I would like to do on occasion, is add a subdirectory, mark it as an application and run a whole different MVC 3 app from that directory. For instance, my site is at http://sol3.net. I am working on a small MVC app for a client and I'd like to publish it on my site so he can take a look at the progress, offer feedback, etc. So, their site would be at http://sol3.net/projectA. Having done this with a test app all I am getting is a 500 error.
Are there any best practices on how to set this up?
And yes, I already know about web.config inheritance problems. Fortunately my web.configs are not too large and I think I have most everything handled there.
NOTE: What I am trying to do is temporarily run a MVC app (App B) from within an app folder on an already active site (App A). App A and App B do not share anything in common and App B will eventually be moved to its own hosting site.
NOTE #2: The Answer...
I believe it is IIS7 and higher that allows you to add a redirection in your root web.config. Here is what I ended up doing instead of doing it via IIS Manager:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<rewrite>
<rules>
<rule name="APP 1 - Sub domain to sub folder" enabled="true">
<match url="(.*)" ignoreCase="true" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTP_HOST}" pattern="^(www\.)?app1\.sol3\.net$" ignoreCase="true" />
</conditions>
<action type="Rewrite" url="app1/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
You would add a subdomain via an alias in your DNS records. Some registrars will let you do this yourself, but some sell this as a feature. A whois on your domain says it's registered with GoDaddy. Check this out. http://help.godaddy.com/article/4652#addsubdomain1
Edit - OrcsWeb allows for remote management of your web site via IIS 7 Manager. This should allow you to edit the host header. http://www.orcsweb.com/blog/brad/iis-7-manager-for-remote-administration-installing-and-connecting-to-a-site/

Resources