可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
Couldn't you submit it via Form and not through the Querystring? That would eliminate the possibility of it being intercepted in the url.
回答5:
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.