Maintaining session information between 2 asp.net calls programmatically? - asp.net

I'm not sure if I'll be clear enough in my explaination to make you guys understand, but I'll try.
Here's my problem:
We have an external site which the users in our company connect to by giving their corresponding username and password. The external site is an ASP.NET website. We want to integrate this website into our intranet portal so that the users don't have to enter their UN/Pwd to login to the website. Since the target website has no provision for SSO, we are simulating the POST request to login.
So far so good.
We are now required to perform an action after the initial login is done, on an another page. We can simulate the corresponding POST request as well. But the problem is since we are not maintaining any session information in our initial POST request, it always redirects to the login screen!
Is there any way to maintain ASP.NET session information between multiple calls done programmatically? Can we create an ASP.NET session id cookie programmatically and then pass it along with our initial request?
Or this is not possible at all?
Any comments are appreciated.
Thanks for your help.
Regards.

Maintaining the state is the responsibility of the other site (typically in a cookie).
You should perform the actions manually, then use Fiddler to compare the HTTP requests and figure out what's wrong.

Related

IIS sending different user page

I have a problem that appears while using concurrent users in IIS/.Net 3.5.
I am logged in using two users to the same server (user1, user2), both are using different computers. If I press on a link to one page using user1 and immediately on the same link to the same page using user2, I receive the sent page to user1 on both computers.
It seems that IIS is caching the requests and sending it to both computers even though that both are logged in using different accounts.
This never happens if you wait a bit before doing that. Is there any specific IIS configuration that caches those requests? How can I link it to per account instead to all? At worst case, how can I disable it?
Any tips are highly appreciated.
ASP.NET has a configurable/extensible output caching mechanism.
You can configure/disable the stock page output caching in web.config, or write your own custom output cache provider and refer to that in web.config.
There's information about it here.

ASP.NET VB.NET Remote Login Portal Setup

Technology
ASP.NET, VB.NET 2.0 (soon to be 4.0)
Overview
I'm writing a Login / Authentication Portal, so that a web application can use it to login a user, and then they can use the application using their credentials.
The login portal will be a separate application, and initially only available via an extranet as well as intranet for certain applications; but future apps will need to authenticate via the web (happy to implement as a separate instance). I basically want other individual applications to be able to authenticate users via this portal.
So that...
A user goes to an application's web url (i.e. www.application.com / http://apps/application - intranet) and clicks "login".
User's browser is redirected to the portal application, with a query
string
www.loginportal.com/login.aspx?url=www.application.com/login.aspx
(or other page).
User fills in their credentials (username, password), and clicks
"login" button.
Browser redirects back to url i.e. www.applications.com/default.aspx or login.aspx and is authenticated and logged in; and can use app.
Completed
I have the authentication itself sorted, and will implement as a class library in the local applications via a dll.
Need
So I basically need to know, how to:-
1. Post data to the portal url (could be different domain).
2. Redirect browser with post.
3. Make sure that the authentication is secure, and not easily hackable (I know how to use urlencode and htmlencode etc) - just not sure about implications of posting data across domains.
Any help greatly appreciated...
Cheers,
Duncan.
Seriously tough stuff, here. If it were me, I'd lean heavily on Windows Identity Foundation. I believe it can support this scenario (haven't actually done it; someone else at my company is developing against it).
OK, so this is the solution I ended up using:
In the original application (the one that needs the authentication; step 1 above) I redirect the user to my login portal, and include the original url as a get parameter.
The user then types in their details, username and password.
Next, the server-side code authenticates them, and redirects to a new page, where I send back to the page an html form which includes the request datetime (for security) along with a encrypted string (including the datetime of the request) of the data I want sent back to the original form.
I also add a JavaScript post method which sends the data to the original url as a form post. Because I'm using the same class library at both ends, I can encrypt and decrypt the data using the same method and the original requesting application has all the user data, including the ability to check the datetime of the request (I allow a set amount of time between the authentication and the picking up by the original app, making sure these are within say 5 minutes.
And job done.
If anyone wants the code, I can provide it, just don't have it with me at the moment, if I remember I'll post it.
Not the most elegant solution, but it works, and it's secure, so I'm happy. :).

How do I restrict the WCF service called by an ASP.NET AJAX page to only allow calls for that page?

I have an AjaxControlToolkit DynamicPopulate control that is updated by calls to a WCF service. I know I can check the HttpContext in the service request to see if a user of the page (and thus, the control) is authenticated. However, I don't want anyone clever to be able to call the service directly, even if they're logged in. I want access to the service to be allowed ONLY to requests that are made from the page. Mainly, I don't want anyone to be able to programatically make a large number of calls and then reverse-engineer the algorithm that sits behind the service.
Any clever ideas on how this can be done? Maybe I'm over-thinking this?
Thanks in advance.
The simple answer is you can't. The complicated answer is you can fudge it with a lot of work, you could for example
Rate limit based on the IP of the caller.
Drop a cookie based upon the session and rate limit on that.
Drop a cookie based upon the page when the page loads and rate limit upon that.
However none is foolproof, and all can go wrong with legitimate requests.
If you really want to restrict this to just this one server making the request, you could add a certificate to that server and check for that certificate. However, you probably can't really limit access to just a single page calling your service.
You could add a lot of additional elements, like headers etc. - but none will really be totally sound - if someone is determined enough, they'll be able to figure out what you're doing, and replicate that.
So really: why do you need to limit this access this badly?
I solved this with a different approach. Instead of trying to secure the service to a single page, I just secured the service by checking HttpContext to make sure the user making the request is authenticated. This relies on ASP.NET Compatibility being enabled on the WCF service class: http://msdn.microsoft.com/en-us/library/ms752234.aspx
Then I have access to HttpContext within the service and can check that the call came from an authenticated user. =D

Is it possible to authenticate on another website?

If I am on a website#1, and I enter my username/pwd for website#2 on a login page that is on website#1, and website#1, behind the scenes, makes a httpwebrequest to website#2 and posts to the login page. If I then navigate to website#2, should I be logged in?
website#2 uses formsauthentication and I call a httpHandler that is on website#2 and pass it the username/password via the querystring.
Should this work?
What you're trying to do is called Single Signon. The way you're doing it, posting values from one site to another, probably won't work because you're using the same technique a hacker might use to trick user into sharing their login information. It's called a cross-site request forgery attack. IIS is configured not to allow that.
Generally, you need a central authentication system that both sites use to share login information. This can be done in several ways, including a shared database-based login system. Google "asp.net single sign on" for more ideas.
Do site #1 and #2 want their users to have single sign on?
If so, read up on single sign on. It's a bigger project than can be addressed here. There is a good book on it though from Wrox :
http://www.amazon.com/Professional-ASP-NET-Security-Membership-Management/dp/0764596985/ref=cm_lmf_tit_10
Or are we imagining something sinister?
If we are imagining something sinister, then evil site #1 would collect the credentials, then automate a browser on the server side to start checking to see if site #2 uses the same password and user combination. Then the server would have an authenticated session. This wouldn't give the user who accessed site #1 an auth cookie, the HttpWebRequest object on the server would get the auth cookie. Site #2 couldn't really do anything to prevent this because a browser request from one computer looks much alike a browser request from another. A well crafted attack would spoof all elements of the browser's request so that it looks like it came from a browser instead of a primitative HttpWebRequest object, which may not even set the user-agent.
Site #2 should stop using passwords and user Id or use 2 factor ID if they are concerned abut this, or do something that requires javascript for logon because spoofing a browser that is executing javascript is harder than spoofing a browser that just sends and receives http requests and responses.
There are too many security issues trying to auto-authenticate between sites. There needs to be a central security provider that both sites belong to so that hand off is completed securely.
We use CA's Siteminder for cross site authentication. Effectively, web 1 creates a unique session id on the siteminder server and passes any credentials and info to it. Siteminder invokes web2 and passes the information by means of session variables. Web 2 retrieves the data from the session and uses it. There's much more going on there but that's the just of it.
To do something like this, I would strongly consider using an out of the box solution as generally coding up custom security generally falls short.
While this can be done on some cases, in the form of an HTTP request with POST parameters, you will not be authenticated once you browse to site #2.
This is because, generally, these sites store a cookie on your end and these are domain-based, which means that even if you grabbed that and stored it yourself from site #1, the cookie name would not match site #2.
Additionally, site #2 may not be easy to authenticate against and this is usually a security concern that developers are aware of. This can be considered an attempt of XSS as well.
In case you're simply doing this for yourself, I'd recommend LastPass and save most of your info in it.
Please reconsider your goals and how to achieve them, this is not the way.
Edit: Link text.
This could work, depending on the security measures in place on website #2. For a secure website, this would fail.
I would recommend against this purely on the basis of good security and good coding/design practices.
If you are unclear what security measures stop this, you should probably educate yourself so you can prevent the same issues on your own site. See http://www.owasp.org/index.php/Top_10_2007
Since both your sites are using FormsAuthentication you can easily configure both of them to share FormsAuthentication encryption schemes.
This will allow you to do Cross Application Authentication automatically :)

How to create a database driven login system

I want to create a website that the login system shouldn't be handled by cookies, but on (a) table(s) in the local (on the server) SQL DB.
Is there a way to do it?
Even no partial way?
What and where should I save instead of the cookie???
ASP.NET uses Session cookies by default to track user requests. If you use Cookieless sessions, you will find the Session ID being appended in all requests from the browser. In many scenarios, this could also be unacceptable.
Even if you decide to hit the database and check for a "LoggedIn" flag upon each request, you still need some way to identify the incoming request as belonging to a particular user. This could be in the form of encrypted values in hidden fields, depending on your security scenario. That said, it's not a much better method than the use of cookies, because any data that comes from the client has the potential to have been tampered with.
Personally, I think Cookies are great to track user requests as long as you encrypt them properly.
You still need some way of telling the users apart. If you don't use cookies, then you will have to transfer that information in url or allow only one user from a single ip address (this is really stupid) ... or something else. Cookies are not that bad :-).
Cookieless ASP.NET
If you need help actually implementing the login system you'll need to include more details about your specific problem.
You can store your usernames and so in a database, but you will still need a way to recognize the user as he/she navigates from page to page. That is the cookies role in this, to persist this login token...
It is possible to implement some other ways of handling this token. One can use the URL or somme hidden fields (as ASP.NET's ViewState) to store this token.
So, yes; it can be done. But it takes some work, since you can't use what ASP.NET already provides you. (ASP.NET has builtin-features to handle this token as a cookie, and also store the credentials in the database.)
Use the SqlMembershipProvider.

Resources