add asp.net pages to an asp classic website - asp.net

I have an asp classic web site and I want to add some new code. I would want to begin to code with .net. Is there an easy way of doing this.
I was thinking an iframe that call my .net pages, but how will I share my user that need to be logged in my asp classic web site.
If I would use an iframe, what would be the best technique to share my user. I was thinking of passing the crypted info in query: test.com?users=[mycrypteduser]. But how would I encrypt it?

I'm pretty sure you can mix aspx and asp files in a single web project. So, create web-proj, then drop your existing website files to it (from within VS). Then, slowly start to refactor your existing site to aspx, as you can, page by page, and create new pages as aspx, of course.
Using IFRAME over this approach will be a lot more work that one may anticipate. But, regardless, you're hitting the problem of 2 unrelated websites in the need to trust each other authenticated sessions - and, this is primarily solved by those websites communicating such information to each other in the background, without the direct involvement of the browser. You need to be able to change the code at both sites (so, you must own both sites). So, if you want to go that route, typically it'd be done this way:
User logs in to your asp site
Your ASP site calls a webservice at your ASP.NET site and informs it that the user will be coming with a particular one-time auth-token in query and that it should be trusted. The emphases here are: the webservice must be well protected by authentication mechanism (otherwise you're risking a huge security issue); the auth-token mentioned should expire after it's used once and only once (otherwise, you're opening your asp.net site for abuse). Typically, your ASP app would call a service at ASP.NET with a signature like this: string GetAuthToken(string username). ASP.NET app should store this info as a record in a database: username, some random and unique string value (e.g. guid), create time (with the precision of at least a second), and time used.
Your ASP app receives a one-time auth token from ASP.NET app.
Your ASP app would need to include this token into the URL used on the frame to a page at ASP.NET site.
Your ASP app would then serve the page with a frame to the browser.
The browser starts displaying the page, then it gets to displaying the frame to external asp.net page
The browser requests the asp.net url, which contains the auth-token
ASP.NET site receives the request and it assumes that the auth token is present and valid; otherwise, exception. Valid token is: never used (time-used in db mentioned in step 2), and valid (its existence in db). As the receiving page validates this token, it immediately checks it off as used. It's the best to put this logic as one atomic operation (e.g. a stored procedure, if you're using MS SQL Server). This way, you can execute both get-token and mark-token-used in a single step. This URL must be anonymous; you must have forms-auth on this site anyways, and this particular handler should be reachable by anon user. If you dislike making that exception, then maybe create an HttpModule, which would inspect every request, and act only on those that are anonymous and are containing the auth-token (by validating the token, and then, as appropriate, interrupting the request or letting it execute); this way, your framed page doesn't have to care about authentication, but it must be forms-auth protected also. I personally would do this that way (http module). Also, if you're sure that relatively short period of time will pass between step 1 and step 2 here (e.g. few seconds max), then do include token expiration in your token-validation logic (validation time must not be later than token-create-time + some number of seconds, e.g. 30) - just for extra security. Otherwise, if you don't implement expiration - imagine a user logging in today, which generates this never-expiring token, and a malicious user somehow getting a hold of the token string. Then, if the authenticated user never visited the page with the asp.net frame, then the token would be usable days, months, years from the moment it's issued, even after the real user closed their account. You don't want this risk. If the login page doesn't redirect to the page with the frame, then make the service call from that page instead (once per session). Ideally, the token should expire 30 seconds or so max after it's created.
If the token is valid, the part of your ASP.NET app that is validating the token would then be responsible for issuing forms-auth cookie. You'll find a ton of examples out there; keywords: FormsAuthentication, create cookie, authenticate user. Make sure that besides inserting the cookie into the response (which is done by default by FormsAuthentication module), you also set the identity of that current/particular request immediately, as until you do, your request is still considered anonymous. If you don't do that (and people do this, but I don't think it's necessary), you will have to redirect that request (which would force the browser to send up the auth-cookie that it just received in the 302 response).
Finally, your framed page receives an ok that the user checks out and that they may view the content that that page generates. Your page streams HTML down to the browser, and the browser shows that content in the frame.
Note that you will not be able to have any sort of client-side scripting (javascript) going on between the page and the frame (security reasons), and that would be another way why I'd rather mix asp with asp.net files (and slowly upgrading the asp part to asp.net), provided that makes sense in other business-related aspects.
Beware of shared-hosting issues related to outbound requests. Some hosts block all outbound traffic; so, if your asp app is in such environment, you won't be able to make that webservice call to asp.net. If you have the asp app making other/unrelated http calls across the internet (e.g. it talks to 3rd-party web services), you're good (it'll work); otherwise, do test this somehow, as you can never be sure. Also, even if your site runs in your own environment, companies often have outbound firewalls in place, so, you might have to request an exception for this.
Remember that the page-refresh will not be an issue, and you do not need to make the get-token call more then once per authenticated session. This is because the browser will, after the first frame load, have an auth-cookie from asp.net site, and the token (even if present in subsequent frame url), will not be validated (remember, the module validates token on anonymous session only; see step 8).
Do think about adjusting cookie expiration settings between the 2 sites. Imagine asp.net auth cookie expiring before the asp auth cookie expires: user reloads the page, and the iframe shows the login page on asp.net - ugly. So, your asp.net auth cookie should probably be set up to expire longer than asp auth cookie (however long you set it as, you won't fix the problem, as it's either wrong to set the cookie to not expire for extremely long time, e.g. 7 days, or it's theoretically possible that a user of your asp site will sit through all that time without touching the page with the frame after they saw it once, and your asp.net cookie will expire). So, do something like this maybe: set asp.net auth cookie to expire in 20/30 minutes (one of those is the default timeout value). Then, have asp app be aware of this timeout value. So, correction to my previous statement of one get-taken call per session. Instead, have the asp call the get-token service every time that you know the asp.net cookie already expired or might expiring soon. In other words, keep track of when you made the last get-token call for each user, and if 15 min (for example, where asp.net cookie expires in 20) has passed since last get-token call, make it again, change the frame url, and the frame will be authenticated once the existing asp.net cookie expires (which would be approx 5 min from that moment, in this example).
I keep coming back to edit this answer :) So, cookie expiration problem - assuming asp.net cookie expires in 20 min, and I told you to set the url on the frame every 15 min, while I also told you to make the token expire in 30 sec - so, those 2 things are conflicting. Hm, I wonder what's the best solution here... Maybe set the get-token to happen closer to asp.net cookie expiration (as in, e.g, at 18 min, but still less than 20), and set the token to be valid for, I don't know, 3 minutes). This would result in 18 + 3 = 21 to overlap the asp.net cookie expiration. All this because the user already has asp.net cookie. So, 18 min after that first cookie was issued, they visit the page with the frame, and the page decides to get another token. This starts token-ticker on asp.net site, and it sets the iframe url with new token. But, since existing asp.net cookie is still valid, the new token will not even be validated (remember the module only validating anon requests with token? Otherwise, you'll have too many db hits if you do it on every request), so the new token will not be used immediately. Eventually, asp.net cookie will expire (in 2 min), and the new token will be validated. If this is a problem (if I omitted some use case that essentially results in the login page displayed within the frame), then maybe you can implement some other mechanism to keep these cookies in place: maybe add code to the login page at asp.net to look for the token in ReturnUrl (decode, then load into NameValueCollection, then look for it as a normal querystring lookup), and maybe communicate back to the asp site something that would signal it to re-request the token when the frame comes back (and what I mean by this, redirect the framed login page, in this case only, back to a special asp script at asp site, which would re-request the token, and then redirect the frame back to asp.net with new token.
I told you it'd be a lot of work. Perhaps there is a standard that involves all this. Check out OAuth (http://oauth.net/) and OpenID (http://openid.net/); those methods are similar to what StackOverflow is offering as login alternate to SO accounts (Google, Yahoo, etc). However, that implies that you actually send the user to the asp.net site to login, then come back to the page that displays content from asp.net site. Perhaps you can combine this with the webservice call that I suggested (get-token ws, redirect top window with token in url to asp.net, asp.net will authenticate and redirect back, then page with frame will display). However, you still have the cookie expiration problem, as you need to constantly be able to get content from asp.net site (whereas, StackOverflow, for example, talks to Google on my behalf only once, during login, and never again during the session), but instead of that messy iframe redirect path that I send you, maybe you can simply repeat the login-to-asp.net-site routine every 15 min (get token, redirect there, validate token, redirect back). If you do this every 15 min at the whole asp site level, you should be fine - and, the user won't even notice this in most cases, as those redirects will be quick.
I'm sorry if this is a difficult read. I hope it helps, though. +1 if it does :)

You can create a new ASP.NET web application, and pull all of your classic ASP pages. Then when you deploy, the ASP.NET web application will overlay your classic ASP.
If you are using some sort of integrated authentication, both the ASP and ASP.NET pages will have access to the same identity. If you created your own authentication layer in the ASP application, you will need to recreate this in ASP.NET (for example, create classes that read/write the same authentication cookies that the ASP pages are using).
However, long term this will introduce some development friction switching between ASP and ASP.NET all the time, so I would really only suggest this approach if you are planning to incrementally convert your entire application from classic ASP to ASP.NET.

You can use NSession http://nsession.codeplex.com/ an open source project with objective to allow ASP Classic to access ASP.NET out-of-process session stores in the same way that ASP.NET accesses them, and thus share the session state with ASP.NET.
I have tried it out and it really works.
Happy Coding!!

When i face this issue, i have found the best solution is usually to use .NET as a web service, and use HTTPRequests in the ASP page to pull the data into your ASP page.
When sharing sessions with ASP and Classic ASP, the most common way is to NOT USE SESSIONS IN ASP, and Use Cookies, Database Cookies actually for the actual session verification, by GUID usually.

Related

How are user logins from a desktop application usually handled?

What is the common(best practice) way of allowing a user to sign in from a Windows desktop application. Some examples of what I mean are Dropbox or Google Picasa. You sign in with your credentials and then the software is permanently signed in.
I assume the communication takes place over HTTPS. Does the client store the credentials to be sent with requests or is there some sort of token generated? Can anyone point me to some resources on how this should be handled?
Logging into a website normally creates a session at the server. The server then has to identify subsequent requests by the session. Typically, there is one of the following two solutions applied:
Session cookie, storing a session identifier
URL rewriting, where the session identifier is appended to every link in the html source
Which approach is taken is site dependent, so if you are writing a general 'for all sites' client, you might have to implement both.
In the former case, your application will have to handle the session cookies, in the second case, your application has either nothing to do - if it caches the html response - or will have to emulate the url rewriting itself.
In both cases be aware that the session will expire at server side after a certain period without any activity, so you might be required to generate such.

Migrate from Classic ASP -> ASP.NET over six months - strategy for session?

I'm using an ASP Classic app that makes use of session state. It's got quite a few pages. I'm slowly migrating to .NET, with an ETA of about six months.
Is it worth changing over the classic asp to use a custom DB session for an implementation of that time frame? Or should I just migrate so features are separate between the apps and no session is shared?
Thanks!
In the past, I've transitioned by maintaining two apps, and passing authenication information between the two at the database layer. When the user requests access to the new ASP.Net app, write an entry into a table with guid(s) and a datetime, then redirect to an authentication page, which checks the table for the corresponding row, which is only valid for a certain length of time (30s), and has a one time use.
If the row exists, grants logged in access under the same username.
a common way of doing this, is supporting both sessions during the migration period, and letting asp.net manage authentication of all resources across asp and asp.net.
IIS 6 and higher has a feature that let's you redirect classic asp resources to aspnet handler. ( i believe this is via wild card application maps)
With this, you will get the login re-directs for not authorized sessions.
If you want to have access to .net session from asp session, a common way is to create a handler in .net (call it "/SessionSynch" for example) and than from asp, you can execute a post to it, to get all necessary session data. Something to consider here is security of course. You want to make sure that your .net handler checks the request, and only reveals session information if your request is coming from appropriate source.
you can also synchronize the info via database.
the one common identification between asp and asp.net you can rely on, is the session cookie, which is easily retrieved from both sides. If you fire up Fiddler, you will notice that upon successful authentication your session cookie will be set. you can then use this cookie from asp to retrieve session info from .net
The two things that I would take into consideration are:
Is persisting session data in a database necessary for my application?
When migrating an old application to a new platform there is a good chance you will run into some snags. Better to change the session storage at the end of the project if there is time.
If the timeline has not already been accepted and you'd just like to try and add another deliverable, this is not something that should take you very long.
The easiest way to do this (as you have mentioned it's short term only) would be to have an intermediate script (asptoaspx.asp?redirect=aspxscript.aspx) that does an automatic form post (user doesn't see it). Here is a pseudocode for that script.
Response write html form with action=aspxscript.aspx
For each session variable in ASP response.write hidden input with name=key and value=value of the session key on the form
Submit the form using javascript
This way when you go from an ASP page to an ASPX page in your application, you would have your session variables ready to use.
Hope it helps!

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

ASP.Net - What is current best practice for tracking state and session variables?

We're creating a new consumer/public-facing ASP.Net web app. There are two concerns:
--Use cookie or cookieless forms authentication?
--If we decide not to use cookies at all, how would you store the data that would otherwise be stored in the cookie (Customer ID, AffiliateID, etc.). Does the ASP.Net authentication framework track something like CustomerID?
For a normal web app there is no good reason to use cookieless authentication - Fear of cookies died out about a decade ago.
For actual data, the session object is generally a better choice than individual cookies - The session cookie is a single value that effectively gives you a key to whatever session data you have stored on the server. There are certain specialized cases where there are problems with using session, for example in multi-server deployments, but in for most applications it is simple and adequate.
The standard forms authentication system does track the username - generally this is enough to look up whatever data you need from your database if you don't want to keep anything in the session.
If you're doing authentication, cookies are the usual method. It's very rare these days that people will have cookies turned off because so many sites already depend on them.
Having said that, ASP.NET does support "cookieless" authentication. Basically it just adds the authentication token as a parameter on the URL. It parses all outbound URLs to ensure that they also include the token information. Personally, I wouldn't bother with this and just go with requiring cookies. There are a few additional headaches when trying to go cookieless (for example, it can make SEO that much harder, because the search engines will see a different URL every time it crawls the page).

Sharing login-system between classic ASP and ASP.Net

A client uses classic ASP to log in to their web based backoffice.
I have written a new ASP.Net app to be included in the backoffice, and I need to utilize the already existing login-system, so that when they are logged in there, they don't need to log in again in the new ASP.Net app.
Logins and passwords are stored as clear text in a SQL Server db, that I can access from my ASP.Net app.
What would be an effective way to integrate these systems?
My current best idea is:
In the link to my ASP.Net app, I link to a "gateway" login-page with their userid and a hashed password + common secret in the querystring. I then compare this to the password of the user in the database... But the problem is, that if this querystring is intercepted, it can be used to access the asp.net site, without actually knowing the username and password...
I am most likely overlooking something simple.
I think your idea is on the right path.
As you probably already know, classic asp and asp.net cannot share the same session state, so you do need to have a mechanism to log from one into the other.
What I would do is: when someone logs in, create a unique GUID that you save in the database for that user. When you jump from one site to the other, pass that GUID into the query string. When you try to auto-log them into the other site, look up that GUID and see if it's attached to anyone. If it is, log them in.
This way you aren't passing anything that a user could guess or decrypt.
How does the classic ASP system maintain login state? "Piggy-backing" off that would be your best bet, by far.
All classic ASP systems I've worked on have used cookies for tracking authentication information, so just read those and compare against the database that you can access.
As the information is stored in a Classic ASP session, could you add a "redirect page" to the classic ASP side of things that is the "entrance" to the new module, and cause this to write the useful data out as cookies, or trigger a POST to your start page? By using cookies or a POST request, you minimise your worry about having the url "hijacked" allowing someone to get into the ASP.net site without username/password.
You are rightly worried about a MITM type attack, possibly through DNS cache poisoning or similar. Depending on your circumstances, it may be enough to mitigate the potential effects of this by adding a time constraint to the login token that is passed across the application boundaries.
The 'GUID in the database approach' is something I have used successfully myself in the past, both for passing users between two applications sharing the same authentication database, and also for 'password reset email' type scenarios. You could 'expire' this by having an additional column on the record specifying the date at which the GUID was added, and modifying your application code to only log in GUID auths which are less than x minutes / hours / days old.
An alternative could be to avoid additional fields in the database by concatenating something like:
UserId + [Value representing current time to nearest x minute / hour /day] + Salt
.. hashing it, then then duplicating your algorithm on the other application and comparing the two generated values.
In general, I think your proposed solution is appropriate to the problem. It is certainly not too complicated.
Couldn't you submit it via Form and not through the Querystring? That would eliminate the possibility of it being intercepted in the url.
If interception is a serious issue then you need to be running the site over HTTPS. Otherwise using the UserID + Nonce that is then hashed by the password is reasonably strong.
Alternatively you could get the ASP app to add a GUID session cookie once logon has been acheived and store that GUID in a DB table. Your ASP.NET can look up the GUID from the cookie to see if logon has been acheived. If you include the ASP session cookie value in the table you can make reasonably sure that the current ASP session is the same session that was used when the GUID was created.

Resources