RE: Authentication design

2003-06-11 Thread Frank Maas
Perrin Harkins wrote (in a discussion with Michael L. Artz):

 Well, I figured that the AuthenHandler already parsed the
 authentication cookie and declared it valid, so I didn't really see
 a point the in doing it at the beginning of every script.  $r-user
 just seemed more intuitive to me.
 
 Well, I'm not sure what's involved in determining $r-user aside from
 reading the cookie.  It may not make any difference.
 
 Here's a typical pattern for this:
 
[...]
 
 The session stuff could be done in a separate phase before the content
 handler, or it could be done on demand when your script calls some
 utility method that knows how to get the current session.  Same with
 the user. 

Isn't this more a matter of 'niceness'? Putting the session/user stuff
in AuthenHandler and then setting the $r-user makes it clear where the
authentication takes place. All other handlers just check if $r-user is
set and need not to bother with sessions and stuff?
Or is there something against this and would you be a supporter of having
it all in the same handler? 

--Frank


Re: Authentication design

2003-06-11 Thread Michael L. Artz
Perrin Harkins wrote:

Well, I'm not sure what's involved in determining $r-user aside from
reading the cookie.  It may not make any difference.
Here's a typical pattern for this:

- Fetch the session key from the validated cookie.
- Load the session using that key.
- Grab the user ID from the session.
- Load the user's data based on that ID.
The session stuff could be done in a separate phase before the content
handler, or it could be done on demand when your script calls some
utility method that knows how to get the current session.  Same with the
user.
Not sure that I quite understand ... what do you mean by load the 
session/user data if it is being done in a handler before content 
phase?  What would you use to store the retrieved data ... pnotes?  
Also, I am not quite sure of the distinction between session data and 
user data.  Wouldn't session data be intrinsically tied to a user?  My 
session table currently looks like [user_id, session_key, session_data, 
login_time, last_access_time].  I guess I am currently using the session 
table to be more of an authentication table, i.e. if you give me a good 
user_id/session_key ticket that matches what is in the database.

I guess my pattern is:
within PerlAuthenHandler
-Check to see if there are passed user/password params.  If so, validate 
params against user/pass in database.  If the params are valid, create a 
new session key, store the session key in the database, and set a cookie 
with the user_id and session_key.
-Otherwise, if there is a cookie, validate the cookie's user_id/session 
against the database one stored in the database.
-If either the params or cookie passed muster, set $r-user and return 
Apache::OK.  If the user passed incorrect parameters, redirect to a 
custom_error form which is the login page.  Otherwise, return Apache::OK 
and do not set $r-user.

within registry scripts:
-If $r-user is set, turn on custom pages and load user preferences.
-Mike



Re: Authentication design

2003-06-11 Thread Peter Bi
There are at least 2 places where the idea can be improved to be even
better:

1) for browsers that do not support cookie, embed the ticket/credential in
the URL so the system works for all browsers

2) the part for ticket verification can be written in C so in case of
dual-server setup (light plus proxy), which is kind of popular now, one can
set it up in the light server to protect static content.

Peter

- Original Message -
From: Michael L. Artz [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Tuesday, June 10, 2003 6:47 PM
Subject: Re: Authentication design

 Well, sorta.  I am actually using a custom module very similar to the
 one found in the cookbook (and AuthCookie, I think), i.e. create a
 PerlAuthenHandler that sets the custom error message to the login page
 and redirects you to it if you pass it an incorrect user/password
 request.  If it the user/pass checks out, I set a session cookie (md5
 sum of stuff), store the session_key in the database (Postgres), and set
 $r-user.  If no user/password or cookie is presented, I just return OK
 for most of the site.  A couple of scripts are login-only, and those
 are protected by an authz handler that makes sure $r-user is set.
 Everything is handled with my custom login forms, none of the crappy
 pop-ups for basic or digest authentication.  So I guess that I am
 usurping the normal HTTP-authentication phase for my own nefarious
purposes.

 I thought that this was a good way to go since I could protect my entire
 application with a single module and a couple lines in the config file,
 as opposed to bundling that authentication code into the beginning of
 *every* registry script that I write.  And, from lurking on the board
 for a long time, I got the feeling that this is how everyone is doing it
  is that a correct assumption?

 -Mike






RE: Authentication design

2003-06-11 Thread Perrin Harkins
On Wed, 2003-06-11 at 03:32, Frank Maas wrote:
  The session stuff could be done in a separate phase before the content
  handler, or it could be done on demand when your script calls some
  utility method that knows how to get the current session.  Same with
  the user. 
 
 Isn't this more a matter of 'niceness'?

I'm not sure what you mean.

 Putting the session/user stuff
 in AuthenHandler and then setting the $r-user makes it clear where the
 authentication takes place. All other handlers just check if $r-user is
 set and need not to bother with sessions and stuff?

Are you asking why anyone would get this on demand instead of always
doing it in an auth handler?  One reason might be that fetching the
session and user is expensive, and you don't know if you'll need it or
not just based on the URL.

 Or is there something against this and would you be a supporter of having
 it all in the same handler?

If using a separate handler makes sense for your app and you like it
that way, then do it.

- Perrin


Re: Authentication design

2003-06-11 Thread Perrin Harkins
On Wed, 2003-06-11 at 08:32, Michael L. Artz wrote:
 Not sure that I quite understand ... what do you mean by load the 
 session/user data if it is being done in a handler before content 
 phase?  What would you use to store the retrieved data ... pnotes?

That's what I've done in the past, although the users of the API didn't
know that.  We just made a get_session() method that returns the
session.  The first time it runs, it does the work.  After that, it
caches the session in pnotes() and gets it there for the remainder of
the request.

 Also, I am not quite sure of the distinction between session data and 
 user data.  Wouldn't session data be intrinsically tied to a user?

Don't you ever have to keep track of anything before you know who the
user is?

When I say user data I mean permanent data; things like the user's
contact info and security allowances, not what's in page 2 of the form
they are filling out.

 My 
 session table currently looks like [user_id, session_key, session_data, 
 login_time, last_access_time].  I guess I am currently using the session 
 table to be more of an authentication table, i.e. if you give me a good 
 user_id/session_key ticket that matches what is in the database.

That's fine if it fits your requirements.

 I guess my pattern is:
 within PerlAuthenHandler
 -Check to see if there are passed user/password params.  If so, validate 
 params against user/pass in database.  If the params are valid, create a 
 new session key, store the session key in the database, and set a cookie 
 with the user_id and session_key.

Isn't the session key unique?  Why put both in the cookie?

 -Otherwise, if there is a cookie, validate the cookie's user_id/session 
 against the database one stored in the database.
 -If either the params or cookie passed muster, set $r-user and return 
 Apache::OK.  If the user passed incorrect parameters, redirect to a 
 custom_error form which is the login page.  Otherwise, return Apache::OK 
 and do not set $r-user.
 
 within registry scripts:
 -If $r-user is set, turn on custom pages and load user preferences.

That all sounds fine to me.

- Perrin


Re: Authentication design

2003-06-11 Thread Michael L. Artz
Hmm, I see now.  I don't really care about users who aren't logged in, 
so I don't know that there is a need to store session data for them.

I guess my pattern is:
within PerlAuthenHandler
-Check to see if there are passed user/password params.  If so, 
validate params against user/pass in database.  If the params are 
valid, create a new session key, store the session key in the 
database, and set a cookie with the user_id and session_key.
  


Isn't the session key unique?  Why put both in the cookie?

Because my session table is indexed off the user_id.  I know that it 
probably won't matter until I have something like 100+ 
nearly-simultaneous users, but I thought that it would be nice to plan 
ahead, just in case.

I guess what I am hearing is the good-ole Perl adage: tmtowtdi.  I think 
that what I have both works and seems to fit my needs just fine, so I 
will stick with it, just wanted to make sure that it wasn't glaringly 
horrible for some reason.  Thanks to all who chimed in.

-Mike



Re: Authentication design

2003-06-10 Thread Michael L. Artz
Jonathan Gardner wrote:

It sounds like you are mixing HTTP-level authentication with 
application-level
authentication.
Well, sorta.  I am actually using a custom module very similar to the 
one found in the cookbook (and AuthCookie, I think), i.e. create a 
PerlAuthenHandler that sets the custom error message to the login page 
and redirects you to it if you pass it an incorrect user/password 
request.  If it the user/pass checks out, I set a session cookie (md5 
sum of stuff), store the session_key in the database (Postgres), and set 
$r-user.  If no user/password or cookie is presented, I just return OK 
for most of the site.  A couple of scripts are login-only, and those 
are protected by an authz handler that makes sure $r-user is set.  
Everything is handled with my custom login forms, none of the crappy 
pop-ups for basic or digest authentication.  So I guess that I am 
usurping the normal HTTP-authentication phase for my own nefarious purposes.

I thought that this was a good way to go since I could protect my entire 
application with a single module and a couple lines in the config file, 
as opposed to bundling that authentication code into the beginning of 
*every* registry script that I write.  And, from lurking on the board 
for a long time, I got the feeling that this is how everyone is doing it 
 is that a correct assumption?

-Mike





Re: Authentication design

2003-06-10 Thread Jonathan Gardner
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On Tuesday 03 June 2003 18:59, Michael L. Artz wrote:
 I am trying to design/implement a fairly simple authentication scheme
 using cookies and such, but wanted to air my design questions before I
 run into too many issues.


It sounds like you are mixing HTTP-level authentication with application-level 
authentication.

While HTTP authentication is pretty cool, unfortunately it is user-unfriendly. 
You won't find hardly any big sites that use it for this reason.

Instead, they use application-level authentication. This is like Slashdot's 
login box, where everything is handled with cookies and HTML forms.

The idea here is that there is a hash attached to each user who browses the 
website. You store variables and information in that hash. When they come 
back, you restore the hash they used last time.

There are several ways to do this. The best practice is to give the user a 
cookie that is a number -- usually an MD5 of something like time, PID of the 
server process, and other random bits of data. The idea is you want a unique, 
unguessable session id.

Then, on your end, you create a table in a database or something like a 
database. You stoe the session id linked to the session data. But how to 
store a hash in a database? You serialize it with Data::Dumper.

The algorithm on each page is pretty simple. If the user is browsing a page 
where you might want to use session data, just check for the session id 
cookie value. If it is not there, you have a choice: do you set a cookie for 
all users when they fail to show a session id cookie, or do you set it only 
under special circumstances (like when logging in)? Either way, you'll want 
to check to see if the cookie was properly set, and at least warn the user 
that cookies need to be enabled. The way I like to do this is to set the 
cookie, then redirect them to a cookie check page. The cookie check page will 
see if the cookie was set. If not, it prints out a warning and explains your 
privacy policy. The idea is to convince the user to change his browser 
setting to accept your cookies. If the cookie was successfully set, you 
redirect back to where you came from.

Once you get the session id, you grab the session data, unserialize it, and 
begin using it. When you are done, remember to serialize the data, and store 
it in the database.

With a little thought, you can probably tweak the system so that it does 
exactly what you need. Don't be afraid of exploring MySQL or PostgreSQL for 
storing the session data. If you are only going to store session IDs, I would 
suggest you explore MySQL. If you may get serious about the database, and one 
day, design a huge database, you are better off starting off with PostgreSQL.

Enjoy!

- -- 
Jonathan Gardner [EMAIL PROTECTED]
(was [EMAIL PROTECTED])
Live Free, Use Linux!
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+5eKLWgwF3QvpWNwRAoWdAKCc1HFa+jxbuiO5+lySY7ViKK7cBQCaA2m5
f7F/121dBpe7ULqyBszvxCI=
=T9Cv
-END PGP SIGNATURE-


Re: Authentication design

2003-06-10 Thread Perrin Harkins
On Tue, 2003-06-10 at 21:47, Michael L. Artz wrote:
 I thought that this was a good way to go since I could protect my entire 
 application with a single module and a couple lines in the config file, 
 as opposed to bundling that authentication code into the beginning of 
 *every* registry script that I write.  And, from lurking on the board 
 for a long time, I got the feeling that this is how everyone is doing it 
  is that a correct assumption?

It is a good way to do it.  The confusing bit is your use of $r-user,
which is generally part of HTTP basic auth.  Cookie-based auth schemes
generally just use an ID in the cookie to tie into server-side data. 
I'm not certain it won't work to use $r-user, but I don't see the point
when you already have a unique identifier in the cookie.

- Perrin



Re: Authentication design

2003-06-10 Thread Michael L. Artz
Perrin Harkins wrote:

I'm not certain it won't work to use $r-user, but I don't see the point
when you already have a unique identifier in the cookie.
 

Well, I figured that the AuthenHandler already parsed the authentication 
cookie and declared it valid, so I didn't really see a point the in 
doing it at the beginning of every script.  $r-user just seemed more 
intuitive to me.

-Mike



Re: Authentication design

2003-06-10 Thread Perrin Harkins
On Tue, 2003-06-10 at 23:43, Michael L. Artz wrote:
 Well, I figured that the AuthenHandler already parsed the authentication 
 cookie and declared it valid, so I didn't really see a point the in 
 doing it at the beginning of every script.  $r-user just seemed more 
 intuitive to me.

Well, I'm not sure what's involved in determining $r-user aside from
reading the cookie.  It may not make any difference.

Here's a typical pattern for this:

- Fetch the session key from the validated cookie.
- Load the session using that key.
- Grab the user ID from the session.
- Load the user's data based on that ID.

The session stuff could be done in a separate phase before the content
handler, or it could be done on demand when your script calls some
utility method that knows how to get the current session.  Same with the
user.

- Perrin



Authentication design

2003-06-04 Thread Michael L. Artz
I am trying to design/implement a fairly simple authentication scheme 
using cookies and such, but wanted to air my design questions before I 
run into too many issues.

I would like the site to be almost entirely publicly accessible, however 
if you log in you get special options in addition to the normal ones. 
Also, there are certain things that you can only do while logged in, 
like post comments.  I figure that this is pretty standard.

I currently have a PerlAuthenHandler that simply sets the $r-user if 
either the correct cookie was given or the correct user/pass parameters 
were passed (remarkably like the cookie authentication listed in the 
cookbook).  It return Apache::OK on all cases except when the 
user/password parameters are invalid, in which case it redirects the 
user to the login page.  I plan on using the $r-user as a test within 
my Apache::Registry scripts to see whether the user has successfully 
logged in and to display the options accordingly.

My question basically centers around the best way to protect the only 
if you login pages.   I was thinking of putting them in their own 
directory and protecting them with a tiny PerlAuthzHandler, which would 
scatter scripts of the same nature in two separate places (i.e. for 
comments, view-create-post), or protect the entire site with a 
PerlAuthzHandler that has a table of all of the only if you login 
pages, which has the drawback of having to change the handler every time 
I add a new script.  Are there any other/better ways to do this?

Thanks
-Mike



RE: Authentication design

2003-06-04 Thread Jesse Erlbaum
Hi Michael --

 My question basically centers around the best way to protect 
 the only 
 if you login pages.   I was thinking of putting them in their own 
 directory and protecting them with a tiny PerlAuthzHandler, 
 which would 
 scatter scripts of the same nature in two separate places (i.e. for 
 comments, view-create-post), or protect the entire site with a 
 PerlAuthzHandler that has a table of all of the only if you login 
 pages, which has the drawback of having to change the handler 
 every time 
 I add a new script.  Are there any other/better ways to do this?

Using the directory structure is a good way to solve this problem.

It is the way Apache likes to work.  Most of Apache's internal systems
are oriented towards directory paths -- .htaccess, Location,
Directory, etc.  As a result, there are plenty of facilities for
managing security in this fashion.

HTH,

-Jesse-


--

  Jesse Erlbaum
  The Erlbaum Group
  [EMAIL PROTECTED]
  Phone: 212-684-6161
  Fax: 212-684-6226