http://qs321.pair.com?node_id=188298


in reply to Is there an off-the-shelf Online Membership solution?

LTjake has asked me to elaborate (via the CB) on how I perform my access control and authentication. Not sure if a "design" should be posted here, however its related to the topic, so here goes:

I've written objects to take care of authentication and access control. The two objects are called session.pm and (pooly named) login.pm

Session.pm manages the session. When a user logs in, the supply their username and password. Session.pm goes and hashes the incoming password, and compares it to the password in the database (using the username).

If the password matches (encrypt and compare) it then creates a "non determinate" token and issues it to the browser via a cookie, and also stores it in a session table alongside the primary (artificial) key of the user.

Access control is a vanilla users -> group, and group -> application style. Access control can also be done at the method level in the same way (ie group -> method). This type of method level control must be explicitly programmed by the application programmer.

The AppFrame is based on cgi::app so for each new application you do a use base 'AppFrame' (which in turn uses CGI::Application). Each time the application is invoked a method in AppFrame goes and checks to see if the user (based on the session id retrieved from the cookie) has access to the page (url) they want to access. ie its all implicit. the application programmer doesnt have to worry about either verifying access, or verifying a session.

The current AppFrame GUI design has a level of menus down the lefthand side for each applicaton. If you dont have access to an application, its icon will not be shown. (This is handled by the poorly named login.pm module.)

The tables used at the back end are:

  • users - contains the users
  • groups - contains the groups
  • usr-grp - maps a user to a group
  • applications - contains all the applications
  • app-grp - which groups have access to which application.
  • session - lists each session, user id, create time etc So its easy to grab the sess_id from the cookie, look up the user's group, and see if the group has access to an application.

    As a short term (non scalable solution) i've make the login method purge any expired sessions from the session table. This was done because the application (as a whole) will only ever have a few users (<100) so performance was not an issue

    I keep away from globals, and rather use "Encapsulated Class data" (as per conway's style.). This way you can do something like $self->{_sess_id}. This variable will be populated using the constructor from the cookie. You can then do something like if $self->_fetch_sess_id() eq $self->{_sess_id} to determine if a session is valid or not.

    Needless to say, because of cgi::apps support of HTML::Template the whole framework is template driven, and can easily have "themes" built into it. The whole deal is not very sophisticated, and certainly not an "Everything" engine, but it works, and is very effective in our context.

    Anyways, hope this makes things a little clearer.