Possibilities of two Web application under a single URL! - asp.net

I have two web applications developed using ASP.Net. I like to provide a link in Application A to access the aspx page in Application B. By this i can access this both application using the single URL.
Is it possible? if it is possible then how should i proceed?
Suresh

A web application by (my) definition has a unique URL. So, no, you can't really have two separate web applications under a single URL. However, you can have multiple applications on the same server, within their own separate virtual directories. This way you can have:
http://www.mydomain.com/ApplicationA
and
http://www.mydomain.com/ApplicationB

The ONLY way to do this would be by sending either
A different GET query-string to access A or B
A different COOKIE indicating whether you want A or B
Server Side detection of some other data ( Ie: user IP, user Client String etc )
However, this sounds like a BadIdea™ and it could become a maintenance headache.

What's the purpose of doing it this way? Not that there's anything wrong per se, but it has a few flags of something that should be avoided. Perhaps if you clarify your question with your need to share a URL, we can give an answer that will help you, instead of just guessing at your requirements.

Are you maybe looking for Server.Transfer?

Related

Asp.net Page access through IP address control

Is it possible to create a page in asp.net that allow the access to a user that has a defined IPaddres? My goal is to add a page "test" (not linked to my website) and I want to define a rule that only a specified IP address can get the access.
How can I implement this throught asp.net?
You could try putting the page(s) in a separate folder and password protect it, then, give the password to your user, so they may access the content. You could go as far as password protecting each file. This helps if your website is password protected or has a login.
You could also create a sub-domain for that user specifically.
These are just a few. I'm sure you'll get better suggestions here on SO!
You could go for a programmatic solution. However, I would use IIS functions to block the access. Less code, easier to configure and no hassle on your developement/test environment.
Assumption: you are using IIS since it is ASP.NET. But other webservers should have similar solutions.
You can add IP restrictions to the directory (meaning you would have to put your page in a separate directory). Example here: http://www.therealtimeweb.com/index.cfm/2012/10/18/iis7-restrict-by-ip
Obviously there are a lot of other and arguably better ways to grant access to a page if what you really want is for a specific "user" or "group" to have access, but assuming that your really want the access control to be based on IP, the answer may still be dependent on peripheral concerns such as what web server you are using. IIS for example has some features for IP based security that you could check out.
Assuming though that you really, really want to check IPs and that you want to do it in code, you would find information about the calling environment in the Request of the current HttpContext, i.e. context.Request.UserHostAddress.
If you want to reject calls based on this information, you should probably do that as early as possible. In the HttpApplication.BeginRequest event you could check if the call is targeted for the page in question and reject the request if the UserHostAddress is not to your liking.
If you prefer to make this control in the actual page, do it in some early page event.
To manage the acceptable IP(s), rather than hard coding them into your checking code, I suggest you work with a ConfigurationSection or similar. Your checking code could be something similar to:
var authorizedIps =
authorizedIpConfiguration.Split(',').Select(ipString => ipString.Trim()).ToList();
isValid = authorizedIps.Any()
&& authorizedIps.Contains(context.Request.UserHostAddress);
If the check fails, you should alter the response accordingly, i.e. at least set its status code to 401 (http://en.wikipedia.org/wiki/List_of_HTTP_status_codes).
NB: There are a lot of things to consider when implementing security features, and the general recommendation would probably stand as "don't do it" - it's so easy to falter. Try to use well proven concepts and "standard implementations" if possible. The above example should not in itself be considered to provide a "secure" solution, as there are generally speaking many ways that restricted data can leak from you solution.
EDIT: From you comment to the answer given by nocturns2 it seems you want to restrict access to the local computer? If so, then there is a much easier and cleaner solution: Just check the Request.IsLocal property. It will return true only for requests originating from the local computer, see HttpRequest.IsLocal Property
(Also, you should really make sure that this "debug page" is not at all published when deploying your solution. If you manage that properly and securely, then perhaps you do not even need the access check any more. If you want debugging options in a "live" environment, you should probably look to HttpContext.Current.Trace or some other logging functionality.)

Running SOAP and RESTful on the same URL

Say we have a website that responds to a host header "kebab-shop.intra.net"
Is is possible to have both SOAP and RESTful in this URL?
That is, both of these are handled within the deployed code.
kebab-shop.intra.net/takeaway.asmx
kebab-shop.intra.net/kebab/get/...
I've been told this can't be done, without much explanation. Like this answer. This could be, I'm a database monkey, but I'd like some thoughts on what options I do or don't have please.
Thoughts so far
Separate host headers eg add kebab-shop-rest.intra.net
Separate web sites
Ideally, I'd like to have one web site, one URL domain name, one host header. Zero chance?
This is IIS 6 with .net 4. And we have some large corporate limitations that mean we are limited to a zip file to drop into the relevant folder used by the web site. This is intended to allow our clients to migrate without incurring the large corporate support, infrastructure and deployment overhead. The co-existence will only be for a month or three.
Edit: I'm asking because I'm not web developer. If my terms are wrong, this is why...
So... I want both SOAP and REST on kebab-shop.intra.net on IIS 6 without complexity.
That is, both of these are handled
within the deployed code.
* kebab-shop.intra.net/takeaway.asmx
* kebab-shop.intra.net/kebab/get/...
Yes, that should definitely be possible. If you have a single WCF service, you could easily expose two separate endpoints for the same service - one using e.g. basicHttpBinding (roughly equivalent to ASMX), and another with webHttpBinding (REST).
The complete URL's must be different - but the first part can be the same, I believe.
If you're hosting in IIS6, you need one virtual directory and that will partly dictate your SOAP endpoint - it will have to be something like:
http://kebab-shop.intra.net/YourVirtDir/takeaway.svc
(or: http://kebab-shop.intra.net/YourVirtDir/takeaway.asmx if you insist on using an ASP.NET legacy webservice).
and the REST endpoint can live inside the same virtual directory and define URI templates, e.g. you could have something like:
http://kebab-shop.intra.net/YourVirtDir/TakeKebab/gbn
or similar URL's.
However: checking this out myself I found that you cannot have both service endpoints "live" off the same base address - one of them has to have another "relative address" associated with it.
So either you add e.g. "SOAP" to your SOAP endpoint
http://kebab-shop.intra.net/YourVirtDir/takeaway.svc/SOAP/GetKebab
http://kebab-shop.intra.net/YourVirtDir/TakeKebab/gbn
or you add something to your REST service
http://kebab-shop.intra.net/YourVirtDir/takeaway.svc/GetKebab
http://kebab-shop.intra.net/YourVirtDir/REST/TakeKebab/gbn
I don't see a reason why you can't. Typìcally your SOAP endpoints will be one specific URLs per service, whereas for resources exposed via REST you will have one URL per resource (following 'URL patterns').
Example URLs for SOAP:
http://kebab-shop.intra.net/soap/service1
http://kebab-shop.intra.net/soap/service2
Example URL patterns for REST:
http://kebab-shop.intra.net/rest/{resourcetype}/{id}/
e.g.: http://kebab-shop.intra.net/rest/monkeys/32/
etc...

Bandwidth Monitoring in asp.net

Hi, We are developing a multi-tenant application in Asp.Net with separate Database for each tenant, in which one of the requirement is to monitor the bandwidth usage for each tenant,
i have tried to search but not found much help on the topic,we want to monitor exactly how much bandwidth is being used for each tenant while each tenant can have its own top level domain or a sub domain or a combination of both.
so what are the available options, the ones which i can think of can be
IIS Log Monitoring means a separate application which will calculate the bandwidth for each tenant.
Log Each Request and Response for a tenant from within the application and then calculate the total bandwidth usage based on that.
Use some third part components if available
So what do you think will be the best approach, also if there is any other way to do this.
Ok, here is an idea (that I have not test, leave that to you)
On global.asax
use one of this function (find the one that have a valid final size)
Application_PostRequestHandlerExecute
Application_ReleaseRequestState
and get the size that you have send with
Response.Filter.Length
No need to metion, that you get the filename of the call using the
HttpContext.Current.Request.Path
This functions called with every single request, so you can get your size and you do the rest.
Here must note, that you need first to test this idea to see if its work, and maybe improve it, and have in mine that if you have compress the pages on server the length is not the correct and maybe you need to compress it on Global.asax to have the actually lenght.
Hope this help.
Well, since the IIS logs already contain the request size and response size, it doesn't seem like too much trouble to develop a small tool to parse them and calculate the total per day/week/month/whatever.
Trying to segment traffic based on host is difficult in my experience. Instead, if you give each tenant their own IP(s) for the applications you should be able to find programs that will monitor bandwidth based on IP.
ADDITION Is the structure of IIS that you have one website to rule them all for all tenants and on login the system forks to the proper database? If so, this may create problems with respect to versioning in that all tenant's sites will all have to have exactly the same schema and would all need to be updated simultaneously when you update the application such that a schema change is required.
Another structure, which sounds like what you may have, is that each tenant has their own website like so:
tenant1_site/appvirtualdir
tenant2_site/appvirtualdir
...
Where the appvirtualdir points to the same physical path for all tenant's sites. When all clients have the same application version, they are all using literally the same code. If you have this scenario and some sort of authentication, then you will need one IP per tenant anyway because of SSL. SSL will only bind to IP and port unlike non-SSL which will bind to IP, port and host. If that were the case, then monitoring traffic based on IP will still be simpler and more accurate as it could be done at the router or via a network monitor.

Who is calling my WebService?

I have a web service that is on an internal server. It can be called from any website on our network.
More and more developers are starting to use it. Current probably 20+ pages use this service, and the number is growing fast. I can see a year from now, someone asking what pages are using this service and what methods.
I would like to log the url of the pages that use my web service as the request come in.
It would also be nice to know the method they are calling.I need to do something in such a way, that it does not affect the client web sites.My first thought was that I could write some code in the global.asax.
I have added some code to the Application_BeginRequest to log the request object details, but there does not appear to be anything about the requesting url.
What am I missing? Should I be looking at a different object?
Thanks.
Without disrupting existing users this is going to be difficult. The httpContect.Current.RequestUrl will just return the URL used to call your web service, not which web page called it.
The closest you can do without disrupting existing apps and forcing developers to change them is to grab the HttpContext.Current.Request.UserHostAddress, so you can at least get the IP of the machine calling your service.
Beyond this, what you might want to consider is adding a parameter to your functions for "CallingApp" and then log that in your code. That's pretty much what we did once re realized that we needed to know which apps are calling our service. We actually have an application monitoring service that uses a GUID for every new app we develop, and we pass that GUID to any web service. It[s extra work but to us it was critical because it allows us to know which apps will be affected when we need to perform updates or take the app server down for maintenance.
Edit - added
As a side note, at the point we realized we needed to track this, we had already been using web services for about a year. When faced with the same problem, we created a new set of web services, and included the extra field for the calling app in all of the new services, and then slowly went back and changed the older programs to point to the new services.
IN retrospect, we wish we had known we would need to do this up front because it created a lot of extra work. I'm guessing you'll be facing something similar if you really want to know exactly who is calling your services.
The only thing you can probably retrieve from the consumer is the IP address without changing your interface.
If you can change this you could do this e.g. by adding authentication and logging who is calling what, or by having some simple "token" principle.
However both methods require you to change the interface and therefore break backwards compatibility - which you should never do.
By always ensuring both back and forward compatibility you should not need to know exactly who is calling your service, but only that it is actually used.
#David Stratton
Thanks for your help. I think your suggestions were great. I accually did something very different, after your answer gave me some new ideas.
I should have mentioned that I was generating the web proxy that most of my users were using to make calls against my web service. My client in general do NOT use the proxy that Visual Studio creates.
Here is what did:
I generated my web proxy client again, and added calls to log the httpcontext of the client before every call. Because the proxy is running on the client, he had access to everything I needed. That allowed me to record everything about the client and the specific call they were making. I realize this would not work for most cases. But all of my clients are internal web sites.
It also had the advantage in that the clients did not have to modify their code at all. I just gave them all a new DLL. Problem solved. I get all the tracking data I want, and they did not have to modify their code.
I was stuck trying to solve the problem from the web service's point of view.
I realize that there is still a whole in this implementation, because someone does not have to use my client proxy to call my service. I guess I could force that at some point in the future. For now, they could let Visual Studio genereate a web proxy for my service. However, if they do that I guess I don't care. That is not the recommened way to call my service. I think the only one doing that is an ASP.NET 1.1 web site. When they upgrade, they will probably switch to my generated proxy.
Without implementing some sort of authentication, there isn't a guraenteeted way of knowing exactly who is calling your service - web metrics are the only way you can gauge what volume of traffic is hitting your service.
I'm sure you already know this but the whole point of a web service isn't to know or care who is calling it.
I have successfully used ...
Dim strReferrer As String = HttpContext.Current.Request.UrlReferrer.AbsoluteUri
to get the calling page that called my WEB API 2 Web Service.

How can I share a session across multiple subdomains in ASP.NET?

I have an application where, in the course of using the application, a user might click from
virginia.usa.com
to
newyork.usa.com
Since I'd rather not create a new session each time a user crosses from one subdomain to another, what's a good way to share session info across multiple subdomains?
You tagged this with ASP.NET and IIS, so I will assume that is your environment. Make sure you have this in your web.config:
<httpCookies domain=".usa.com"/>
If your 2 subdomains map to the same application, then you are done. However, if they are different applications you will need to do some additional work, like using a SQL Server based Session storage (and hacking the stored procedures to make sure all applications share the same session data) or with an HttpModule to intercept the application name, since even with shared cookies and the same machine key, 2 applications will still use 2 different stores for their session data.
Track your own sessions and use a cookie with an appropriate domain setting, ie. .usa.com.
Alternatively, if you're using PHP, I believe there's a setting to change the default domain setting of the session cookie it uses, that may be useful too.
The settings you're looking for are:
session.use_cookies = 1
session.use_only_cookies = 1
session.cookie_domain = .usa.com
I recently went thru this and learned the hard way. Localhost is actually considered a TLD. Cookie domains require at least a second level domain - test.com. If you want cookies to work for a domain and all it's sub-domains, prefix with a '.' - .test.com.
When running/debugging locally, setting a domain of localhost will fail, and it will fail even if the domain is set properly because visual studio uses localhost by default.
This default localhost can be changed in the project properties so that the project will actually run at cookie domain test.com. Essentially, if the address in the browser matches , you can get it to work.
My issue is documented here: Setting ServiceStack Cookie Domain in Web.Config Causes Session Id to Change on Every Request
Hope this helps.
If you're using PHP, one hack would be to make a little include script (or two) to do the following:
1 Serialize your $_SESSION array
2 Pass that string as a hidden input, making all your links to those buttons in separate forms using POST.
3 Also include a boolean hidden input to let your script know whether it needs to use the current session or unserialize $_POST['session']
4 Deploy this across your site, calling things where appropriate
I wouldn't do this if there's actually a sanctioned way to transfer a session. I hope you've at least considered using cookies.
Matt's answer is definitely the way to go if you have multiple subdomains pointing at the same IIS app (which is exactly the situation I have right now, using wildcard DNS and then doing subdomain 'sniffing' on the receiving end).
However, I wanted to add something that I experienced in case anyone is finding that this is not working for them. Setting the httpCookies line alone didn't do it for me, I had to add a machineKey entry into my web.config file:
machineKey decryptionKey="12...D1" validationKey="D7..8B"
Particularly odd since I am not in a web farm setup (unless AWS/EC2 is effectively acting as such).. As soon as I did this, it worked like a champ.

Resources