Author |
Topic |
|
work mule
Senior Member
USA
1358 Posts |
Posted - 20 October 2002 : 08:30:35
|
Authentication & Member Abstraction v1.00 [BETA]
Download: Zip File @ Snitz Bitz
Demo: This isn't something which lends itself well to visual demonstrations. Sorry.
DISCLAIMER This mod should still be considered under development until extensive testing has been completed. Please don't install this if you're not familiar with scripting and how the forum works.
Gosh, where do I start explaining this one??
This is based upon a discussion which took place over a year ago. I've read papers and articles on the subject of session hijacking, client authentication, etc. but couldn't quite decide on how I would do something like this.
Now that the sites (where I work) are going to depend on the forum members table for the entire site and the recent upgrades in Snitz, I had to sit down and get this written. I've spent a lot of time thinking of how to best implement something like this and it's taken many long nights and a couple of rewrites to get this where it is now.
So what's it do?
Hopefully I can explain this properly, otherwise if you're the slightest bit interested, please d/l the zip file. In it I've provided documentation on the properties and methods of the class which might better explain what this does and might be capable of.
The purpose is to provide access to specific member properties independently of the forum code anywhere on the site. Getting access to these properties can be done with a single file (dependent on inc_sha256.asp for authentication) without requiring additional includes and the overhead of initializing forum variables where they are not needed.
First, the simple stuff.
Basically it manages specific user information within the session collection. When someone visits the site, it checks for session information and loads from the database if needed (registered members initiating new sessions). The information for the member is then available through various properties and/or methods for the life of the member's session.
This is an example of the various properties and how they could be used to set variables or check access to sections or possibly even private forums (needs to be tested and requires a bit more modifications to the forum).
TYPE OF INFORMATION - PROPERTY UserName = objUser.UserName Password = objUser.Password MemberLevel = objUser.MemberLevel Registered = objUser.Registered Subscriber_Mag = objUser.Subscriber_Mag (something I need for my site) Subscriber_Web = objUser.Subscriber_Web (something I need for my site) Site_Admin = objUser.Site_Admin (something I need for my site) Site_Staff = objUser.Site_Staff (something I need for my site) Access to Custom Section: "section1" = objUser.CheckCustomAccess("section1") Access to Custom Section: "section2" = objUser.CheckCustomAccess("section2") Check if Forum Moderator: Forum ID - 521 = objUser.ForumModerator(my_Conn,521) Check for Access to Private Forum: Forum ID - 2 = objUser.PrivateForumMember(my_Conn,2)
This beauty of this code is it's independence ('cept for a handful of variables and the sha256 file) which means that it can be used within the forum code and anywhere else on a site. There are also benefits for the forum which can be realized through some additional modification. For example, chkUser functions could be modified to check member properties before issuing a query to the database.
Second, the hard stuff.
For myself, something which was more important than extending the member properties across the site, was attempting to work on session management/authentication. If you consider the current setup. If someone captures a member's cookies, saves the cookies information onto their machine, if everything matched (username/encrypted password string) the person would be able to post under that person's account. At that point, the only way to reset the persistant cookie, is by changing the password on the account.
This code attempts to make it harder for that type of stuff. How this is done, is when someone logs in, a session key (or authenticator as some call it) is set on the client. It's also stored in the session and the database. Subsequent page visits, the keys in the cookie and the session will be compared. After a certain period of time has passed, the session key will be validated - comparing the client key with the database key. If they match, a new set of keys will be issued. If they don't match, the member will have to reauthenticate by logging back in with their username and password.
When would session keys be different? Person A logs in - a session key is assigned. Person B captures the cookie - appears valid. Person A's session timeout (not the same as IIS Sessions) passes, the current key is validated, matches and a new key is issued. Soon afterwards, Person B's session timeout has been reached. Since Person A has been reissued a new key, Person B's client key and the one in the database will not match. Person B is now locked out.
Another example, if you were using someone's computer to demo something on the forum (or a member at a pubic library), had the "Save Password" box checked and forgot to logout, that cookie with your login would persist on that person's computer. They would then be able to post and look at anything which didn't require a password. With session authentication, you would be able to login at your computer and force the session key to reset.
With how this is implemented, you could force all of your members to reauthenticate through the login page by simply resetting all session keys or AUTHKeys in the database. The member's password could remain unchanged.
The only downside with this is that for people who visit the site from home and work, they would be in effect logging themselves out from the other computer. Accounts used by multiple people would also knock each other out also. Granted it might be an inconvenience, but when it comes to security, inconvenience sometimes has to be given up for the sake of security.
Another advantage of session keys like this, is that the key is composed of the timestamp, username and a unique salt/string for each member (for SQL Server and/or Windows Script 5.0+ users, this key is a GUID with {-} stripped out so it becomes 32 characters). This could eventually replace the passwords in the cookie. If the session keys match, then pull the password out of the session if needed.
Why pull passwords out of the cookie?
Anyone can download Snitz, open it up and see it uses SHA256. No secrets there. If someone managed to get a hold of someones encrypted password, it wouldn't be difficult to run the SHA256 function against a dictionary and compare the encrypted results with that of the member's encrypted password. When two encrypted strings match, they just have look at what they encrypted to get the match. Seeing that many people use ordinary words as passwords, it's not an impractical way to figure out a user's password. That's why it's recommended to salt something like a session key or password.
So what's next?
TESTING, TESTING AND MORE TESTING.
I would like to get some feedback regarding the practicality of this and more importantly if there's something I've seriously overlooked or royally botched up. |
Edited by - work mule on 20 October 2002 08:50:22 |
|
PeeWee.Inc
Senior Member
United Kingdom
1893 Posts |
Posted - 20 October 2002 : 09:07:21
|
It looks very good, a great idea
on a scale of 1 - 10 how hard is it to install this? |
De Priofundus Calmo Ad Te Damine |
|
|
work mule
Senior Member
USA
1358 Posts |
Posted - 20 October 2002 : 09:56:01
|
There are a few lines of code that I'm not sure of the compatibility between databases. It's nothing fancy and could easily be rewritten. In order to use classes, it does require that the version of Microsoft's Visual Basic Scripting Edition is at least 5.0 or higher. For more information on VBScript versions, click here.
To install this, it requires:
Database Modifications: Two fields to be added to the MEMBERS & MEMBERS_PENDING tables (however, latter is probably not necessary).
File Modifications: Adding code to 4 files: config.asp - add 2 blocks of code (1 line each) inc_header.asp - add 4 blocks of code (1 block of 9 lines, 3 blocks of 1 line each) inc_header_short.asp - add 1 block of code (10 lines) login.asp - add 1 block of code (1 line)
Add File: inc_authentication.asp
Test Files: ztest-authentication-inline.asp ztest-authentication-lite.asp ztest-authentication-template.asp inc_displaycollections.asp
There's an install.txt file which provides more detail. I made copies of the four files from the Snitz download and added in the modifications and identified the changes with "Authentication Mod", similiar to how Davio tagged his Poll Mod. They shouldn't be hard find.
The modifications I referenced above will allow for session authentication throughout the forum. It will also extend your member properties to the rest of your site by including inc_authentication.asp & inc_sha256.asp and setting the necessary variables.
Further integration into the forum itself will take time to work out in order to ensure the modifications aren't messing things up. |
Edited by - work mule on 20 October 2002 10:02:17 |
|
|
GauravBhabu
Advanced Member
4288 Posts |
Posted - 20 October 2002 : 11:41:45
|
select case Request.Form("Method_Type")
case "login"
strEncodedPassword = sha256("" & Request.Form("Password"))
select case chkUser(strDBNTFUserName, strEncodedPassword, -1)
case 1, 2, 3, 4
Call DoCookies(Request.Form("SavePassword"))
strLoginStatus = 1
' #################### Authentication Mod ###################
objUser.SetNewSessionKey my_Conn, strDBNTFUserName, strEncodedPassword,"", getMemberID(strDBNTFUserName)
When chkUser is called MemberID variable is also populated, so you can use MemberID, instead of calling the getMemberID function. Will save one DB call.
Looks like we are working in the same direction. I am developing separate classes to access DB, authentication and page layout. |
|
|
work mule
Senior Member
USA
1358 Posts |
Posted - 20 October 2002 : 17:24:39
|
My goal is to eventually replace this
select case Request.Form("Method_Type")
case "login"
strEncodedPassword = sha256("" & Request.Form("Password"))
select case chkUser(strDBNTFUserName, strEncodedPassword,-1)
case 1, 2, 3, 4
Call DoCookies(Request.Form("SavePassword"))
strLoginStatus = 1
' #################### Authentication Mod ###################
objUser.SetNewSessionKey my_Conn,strDBNTFUserName,strEncodedPassword,"",getMemberID(strDBNTFUserName)
' ############################################################
case else
strLoginStatus = 0
end select
case "logout"
Call ClearCookies()
' #################### Authentication Mod ###################
objUser.InvalidateCookies()
' ############################################################
end select
with this
select case Request.Form("Method_Type")
case "login"
strEncodedPassword = sha256("" & Request.Form("Password"))
' #################### Authentication Mod ###################
objUser.ValidateSession my_Conn,strDBNTFUserName,strEncodedPassword
If obj.Registered = 1 Then
MemberID = objUser.UserID
strLoginStatus = 1
Else
strLoginStatus = 0
End If
' ############################################################
case "logout"
' #################### Authentication Mod ###################
objUser.InvalidateCookies()
' ############################################################
end select
ValidateSession method will call the SetNewSessionKey method if the username and password are valid. I would have to make sure I have provided for all of the functionality of DoCookies().
Once the session is validated, if the username/password are valid, then a lot of properties will be available through the class. ChkUser can be modified to reference the class properties when the member name passed is the same as the user.
There's quite a few places I'm looking into, but I need to test it out before I post them. |
|
|
e3stone
Average Member
USA
885 Posts |
Posted - 20 October 2002 : 17:38:21
|
Dave, I didn't know anyone was developing something like this. LOL.... I'm currently working something very similar...if not the same thing. I haven't downloaded your code yet, but I was thinking about it just to compare our implementations. I've only been working on mine about a week, so obviously yours is much further along and more functional. |
<-- Eric --> |
Edited by - e3stone on 20 October 2002 17:38:43 |
|
|
work mule
Senior Member
USA
1358 Posts |
Posted - 20 October 2002 : 18:27:28
|
This might be worth posting here to provide insight into the extent of this class.
CLASS PROPERTIES
All Properties are Read Only unless specified otherwise.
Where objConn is listed, this is referencing the connection object which has been created outside of the class.
Public UserID() The user's member id
Public UserName() The user's username
Public Password() The user's password
Public MemberLevel() The user's membership level as stored in the database.
Public Registered() Is the user registered and logged into website? [0:no;1:yes;]
Public CheckCustomAccess(ByVal listname) This property is unique, but provides great flexibility. It requires the name of a custom list, which it will then call an internal method (GetCustomUserList) to retrieve the list and check whether or not the user is in the list. Returns a value of 1 if the username was found in the list, otherwise a value of 0 will be returned if no match was found.
The following properties have not been fully tested, but are made available for testing and as an example of how this class can be expanded to provide more user information.
Public ForumModerator(objConn,ByVal forumid) Requires an id of the forum which is being checked for Moderator rights. Returns a value of 1 if the user has been assigned Moderator rights for the specified forum, 0 if not.
Public ForumModeratorList(objConn) This property will return a list of all forums for which the user has been assigned to as a moderator. This property will send an array as the returning value.
Public PrivateForumMember(objConn,ByVal forumid) Requires an id of the forum which is being checked to see if the user has been granted access. Returns a value of 1 if the user has been granted access for the specified forum, 0 if not.
Public PrivateForumsList(objConn) This property will return a list of all private forums for which the user has been granted access. This property will send an array as the returning value.
The following properties don't have direct application into the Snitz Forums, but are provided here as examples of how this can be extended for different website needs.
Public Subscriber_Mag() Is the user a subscriber to the magazine? [0:no;1:yes;]
Public Subscriber_Web() Is the user a subscriber to the website (paid)? [0:no;1:yes;]
Public Site_Admin() Is the user a site administrator? [0:no;1:yes;]
Public Site_Staff() Is the user a member of the staff? [0:no;1:yes;]
Add more Properties as needed... - can add for specific areas of a site - compare membername against an array of authorized members
One note about the CheckCustomAccess property, this allows you to check if this user is part of a list or group of users. The lists right now are hardcoded arrays (quick development), but could easily be modified to look check against a list in the Application or Session Collections, look in a hardcoded list or even issue a db query.
The Forum Moderators and Private Forums is an example where I took the same idea I had for the CustomAccess functionality and made it more robust. In both of these cases, an array of forum id's is managed in the session which eliminates having to issue a query to check if the member has moderator rights or access to a private forum. This information persists for the life of the session (either the IIS session expires or the member logs off). |
|
|
bhmortim
Starting Member
6 Posts |
Posted - 11 November 2002 : 11:54:13
|
This is great work and something that I really need. I tried to install this and play with it. Unfortunately I just get ASP errors when I try to run the scripts. I went through the install steps that were mentioned several times. Am I missing something else I need to do?
-b |
|
|
Radianation
Junior Member
USA
186 Posts |
Posted - 11 November 2002 : 17:52:11
|
Great idea. I've been looking for something like this, but I'm hesitant to test it on the live forums. Perhaps I'll just have to setup a test forum on my server for something like this. Thanks for coding this.
- Rad! |
|
|
XavierSlater
Junior Member
United Kingdom
137 Posts |
Posted - 11 November 2002 : 18:59:32
|
This is a really neet offshoot of making Snitz more secure, and from the point of view of webmasters making it easier to integrate and control content access, particularly if you deal with "premium" customers.
I will watch this develop with keen interest. |
|
|
|
Topic |
|
|
|