Reputation: 4965
I have a current system using IIS 6 and 7, written in ASP.NET with C# in .NET 4.
My purpose is to hide the url completely (as per client request). i.e. https://myapp.it.mydomain.com/Secure/folder1/folder2/folder3/someView.aspx must be https://myapp.it.mydomain.com/ or at least a unfirm non changing page: https://myapp.it.mydomain.com/constantView.aspx
Currently, we make use of Response.Redirect
for all navigation items, and some direct links.
We also have some minor usage of query strings, but more dependent on cross-page post backs.
We do not have any means of URL masking in place and are looking to provide a mechanism to do so.
I'm already aware of a few method to perform URL Masking, but would like SO's opinion in the easiest to implement solution.
Easiest, is referring to time to implement. i.e. Changing our calls to use Server.Transfer exclusively is not an option.
ASP.NET Routing
seems like a fair solution, but needs work on all query strings as I understand it, to map where we need them to. I am not clear if this can provide hiding for all pages instead of one to one mapping.
Using framesets/iFrames is also not an option, as it causes many complications with the existing solution.
As I understand it, the URL Rewrite Module
may be my best solution.
I'm hoping this question can lead to a good list of possibly solutions, and perhaps methods that I have not already been made aware of.
edit
A more clear question with current situation:
We are using IIS 6 (thus the IIS 7 rewrite module is out of the question). Is there a way to provide URL cloaking/masking which will not break existing code which uses Page.Referrer (in ASP.NET) and query strings?
The idea is to make the address bar always appear to be the same. Even a JavaScript hack is acceptable.
Upvotes: 5
Views: 21813
Reputation: 12351
A bit unclear...I was going to use comment, but the length of this "comment" won't do...
IMHO:
if you are saying response.redirect
is how its currently meeting the requirement, then that (guess) seems to say, redirection is dependent on some query values. If so, the "hiding" doesn't really work - I can simply provide the same query to get to the same result(ing) page(?).
same with server.transfer
- its "repeatable" in any case (so whatever it was the url was supposed to hide, isn't really being hidden (unless I completely missed the gist of the question).
Framesets/iframe etc. - they don't hide anything, its trivial to figure out where the source pages are (e.g. IE/Chrome/Safari/FF developer tools).
url re-writing/routing: well, in order for a url to be re-written or routed, it must (first) be requested so whatever was supposed to be hidden, wasn't (in the first place).
A client's (browser or browser plugin) requests can always be inspected/seen (and without security measures, can be tampered with).
Perhaps it would be better if you explained what it is that needs to be hidden, and why. Urls are just resources to 'something' - so it seems that you really need to protect that 'something', not really the url per se(?). You may get better suggestions....
Some ideas ("easy" is relative):
Use web services and client side scripting. Your UI is driven entirely by script (aka "one page applications"). You can add security to your endpoint in ways you deem fit so that even if the client request is inspected, the endpoint requirements can't be met by spoofing - e.g. an "interim proxy" - your script calls the proxy, the proxy, being server side, does validation + request params, makes the actual request to the endpoint. Since the request is done in the background (server side), the client has no knowledge of the endpoint - therefore it can't be inspected nor seen nor tampered with. You now have a basic HTML "front end" web site completely separate from another web app that does the work. Only the front end web site and its urls are public.
Really not unlike ASP.net Web Forms Postback (if you really think about it). Single page, UI is driven based on user interaction - there is always going to be only 1 url. Interaction -> processing. Results depend on user interaction, certain requirements. A good example is the ASP.Net Web Forms Wizard Control - the "steps" don't equate to different urls. Just like the above, the actual processing can be done in the same web app or in a completely separate web app (web services) - so you can think of having a "front end" web site completely separated from whatever processing web app (only the former's urls are public).
Same with ASP.Net MVC - your Controllers manage whatever View you want to render given some interaction and/or request restrictions (e.g. HttpPost only).
Still, all the above don't pass the "unrepeatable" test without adding more stuff - e.g. RECAPTCHA at which point you should ask yourself if its appropriate for all your users. At some point, if its not meant to be "public", then authentication becomes the answer.
Update:
Anyway, not without getting a better understanding of what is really being protected. If a URI must be hidden then the 2 tier structure - (1) frontend, (2) backend is my personal choice. This likely means a web service architecture.
If I'm overthinking this, and its a matter of some "confidential" name in the url (not really processes), then DNS could be a trivial solution (CNAMEs).
Upvotes: 1
Reputation: 179
You can use for Webforms and MVC Routing feature which is available from version ASP.NET 3.5
Here some examples:
Void RegisterRoutes(RouteCollection routes)
{
Routes.MapPageRoute(
“product-browse”, // route name
“products/{category}”, // URL with params
“~/Products.apsx” // Web forms page to handle it
);
}
Void Application_Start()
{
Registerroutes(RouteTable.Routes);
RouteTable.Routes.MapPageRoute("Product", "Product/{Name}", "~/Product.aspx"
// or simply
routes.MapPageRoute("Customers", "Customers", "~/Customers.aspx");
routes.MapPageRoute("CustomerDetails", "Customers/{CustomerId}", "~/CustomerDetails.aspx");
}
// here how you can get url
string url = Page.GetRouteUrl(“product-browse”, new { category = “software”});
string name = Page.RouteData.Values["name"].ToString();
// This some webform aspx syntax of use:
<asp:HyperLink ID="hyper" runat="server"NavigateUrl='<%# "Product/laptop"%>' Text='<%# Bind("ProdctName") %>' ></asp:HyperLink>
<img src="<%= Page.ResolveUrl("Styles/Images/Product.jpg") %>" height="65px" width="65px" />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Id" HeaderText="Id" ItemStyle-Width="30" />
<asp:BoundField DataField="Name" HeaderText="Name" ItemStyle-Width="150" />
<asp:BoundField DataField="Country" HeaderText="Country" ItemStyle-Width="150" />
<asp:HyperLinkField Text = "View" DataNavigateUrlFormatString = "~/Customers/{0}" DataNavigateUrlFields = "Id" />
</Columns>
</asp:GridView>
Do not use UrlRewriter.NET . This is old technology. MVC also prefer Routing 4.0
Upvotes: 0
Reputation: 3213
You have an excellent breakdown of all the possible solutions for your purpose here: http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx
But based on your request, I personally think that URL rewriting is your best bet, as you would only need to add rewriting rules in the web.config file, so its the easiest to implement solution. For IIS6 I myself in the past have used Intelligencia UrlRewriter.NET
Upvotes: 2
Reputation: 2291
Server.Transfer is the best way for you maintain the same url, but in your case it's not an option. Another way is to Load dynamic usercontrols in the main page.
With dynamic user control you can control what you want to appear in the page, but this is a breaking solution for what you have, i think. Url rewriting and routing, you will have diferent url you will not maintain the same url. considering that you want to enter the pages from url. In .net routing the url must be unique, two routes with the same url are prohibited.
If you want to maipulate what is now implemented the best solution is url rewrite.
Upvotes: 1