Asp.net Page access through IP address control - asp.net

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.)

Related

Stop Direct Page Calls to Ajax Pages

Is there a "clever" way of stopping direct page calls in ASP.NET? (Page functionality, not the page itself)
By clever, I mean not having to add in hashes between pages to stop AJAX pages being called directly. In a nutshell, this is stopping users from accessing the Ajax pages without it coming from one of your websites pages in a legitimate way. I understand that nothing is impossible to break, I am simply interested in seeing what other interesting methods there are.
If not, is there any way that one could do it without using sessions/cookies?
Have a look at this question: Differentiating Between an AJAX Call / Browser Request
The best answer from the above question is to check for a requested-by or custom header.
Ultimately, your web server is receiving requests (including headers) of what the client sends you - all data that can be spoofed. If a user is determined, then any request can look like an AJAX request.
I can't think of an elegant method to prevent this (there are inelegant and probably non-perfect methods whereby you provide a hash of some sort of request counter between ajax and non-ajax requests).
Can I ask why your application is so sensitive to "ajax" pages being called directly? Could you design around this?
You can check the Request headers to see if the call is initiated by AJAX Usually, you should find that x-requested-with has the value XMLHttpRequest. Or in the case of ASP.NET AJAX, check to see if ScriptMAnager.IsInAsyncPostBack == true. However, I'm not sure about preventing the request in the first place.
Have you looked into header authentication? If you only want your app to be able to make ajax calls to certain pages, you can require authentication for those pages...not sure if that helps you or not?
Basic Access Authentication
or the more secure
Digest Access Authentication
Another option would be to append some sort of identifier to your URL query string in your application before requesting the page, and have some sort of authentication method on the server side.
I don't think there is a way to do it without using a session. Even if you use an Http header, it is trivial for someone to create a request with the exact same headers.
Using session with ASP.NET Ajax requests is easy. You may run into some problems, like session expiration, but you should be able to find a solution.
With sessions you will be able to guarantee that only logged-in users can access the Ajax services. When servicing an Ajax request simply test that there is a valid session associated with it. Of course a logged-in user will be able to access the service directly. There is nothing you can do to avoid this.
If you are concerned that a logged-in user may try to contact the service directly in order to steal data, you can add a time limit to the service. For example do not allow the users to access the service more often than one minute at a time (or whatever rate else is needed for the application to work properly).
See what Google and Amazon are doing for their web services. They allow you to contact them directly (even providing APIs to do this), but they impose limits on how many requests you can make.
I do this in PHP by declaring a variable in a file that's included everywhere, and then check if that variable is set in the ajax call file.
This way, you can't directly call the file ever because that variable will never have been defined.
This is the "non-trivial" way, hence it's not too elegant.
The only real idea I can think of is to keep track of every link. (as in everything does a postback and then a response.redirect). In this way you could keep a static List<> or something of IP addresses(and possible browser ID and such) that say which pages are allowed to be accessed at the moment from that visitor.. along with a time out for them and such to keep them from going straight to a page 3 days from now.
I recommend rethinking your design to be sure that this is really needed though. And also note IPs and such can be spoofed.
Also if you follow this route be sure to read up about when static variables get disposed and such. You wouldn't want one of those annoying "your session has expired" messages when they have been using the site for 10 minutes.

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.

Prioritise ASP.NET requests

I would be surprised if this is possible, but you never know.
Is there a way in which I could prioritise ASP.NET requests? For example, if the request is a NEW request (coming from Location X) I would like it to take priority over a request coming from a known location.
This will be running under IIS 7 so can I make use of the integrated pipeline to pre-process requests before they take threads out the ThreadPool?
Hmmm. Any feedback welcomed, even if it's to say No!
Thanks
Duncan
I don't think what you're after is possible in the truest sense of what you're asking for, but it might be possible to 'simulate' what you're after at the application level. John's right, they're processed first come, first served. But you might be able to give some kind of priority to your web application by setting a cookie for all visitors, and checking if that cookie is present before you render your homepage. If it is not present, you could assume that the request is new and therefore continue to render your homepage (or whatever). If it is present, you might choose to redirect them to another page (or perhaps a cached copy of your page).
Like I said, this isn't the 'truest' sense of what you are after, but if your homepage is particulary process intensive right now, and you want some way to separate recurring visitors from new visitors, this might do the trick.
Since you've asked, though - I'd have to ask you why it is necessary in your implementation to prioritise requests as you have mentioned. Is load on your web server a problem, and you want to appear more responsive to new customers?
Just hazarding a guess - interesting question, though! :)
Best,
Richard.

Possibilities of two Web application under a single URL!

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?

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