1CGI::Ex::Auth(3)      User Contributed Perl Documentation     CGI::Ex::Auth(3)
2
3
4

NAME

6       CGI::Ex::Auth - Handle logins nicely.
7

SYNOPSIS

9           use CGI::Ex::Auth;
10
11           ### authorize the user
12           my $auth = CGI::Ex::Auth->get_valid_auth({
13               get_pass_by_user => \&get_pass_by_user,
14           });
15
16
17           sub get_pass_by_user {
18               my $auth = shift;
19               my $user = shift;
20               my $pass = some_way_of_getting_password($user);
21               return $pass;
22           }
23
24           ### OR - if you are using a OO based CGI or Application
25
26           sub require_authentication {
27               my $self = shift;
28
29               return $self->{'auth'} = CGI::Ex::Auth->get_valid_auth({
30                   get_pass_by_user => sub {
31                       my ($auth, $user) = @_;
32                       return $self->get_pass($user);
33                   },
34               });
35           }
36
37           sub get_pass {
38               my ($self, $user) = @_;
39               return $self->loopup_and_cache_pass($user);
40           }
41

DESCRIPTION

43       CGI::Ex::Auth allows for auto-expiring, safe and easy web based logins.
44       Auth uses javascript modules that perform MD5 hashing to cram the
45       password on the client side before passing them through the internet.
46
47       For the stored cookie you can choose to use simple cram mechanisms,
48       secure hash cram tokens, auto expiring logins (not cookie based), and
49       Crypt::Blowfish protection.  You can also choose to keep passwords
50       plaintext and to use perl's crypt for testing passwords.  Or you can
51       completely replace the cookie parsing/generating and let Auth handle
52       requesting, setting, and storing the cookie.
53
54       A theoretical downside to this module is that it does not use a session
55       to preserve state so get_pass_by_user has to happen on every request
56       (any authenticated area has to verify authentication each time - unless
57       the verify_token method is completely overridden).  In theory you
58       should be checking the password everytime a user makes a request to
59       make sure the password is still valid.  A definite plus is that you
60       don't need to use a session if you don't want to.  It is up to the
61       interested reader to add caching to the get_pass_by_user method.
62
63       In the end, the only truly secure login method is across an https
64       connection.  Any connection across non-https (non-secure) is
65       susceptible to cookie hijacking or tcp hijacking - though the
66       possibility of this is normally small and typically requires access to
67       a machine somewhere in your TCP chain.  If in doubt - you should try to
68       use https - but even then you need to guard the logged in area against
69       cross-site javascript exploits.  A discussion of all security issues is
70       far beyond the scope of this documentation.
71

METHODS

73       "new"
74           Constructor.  Takes a hashref of properties as arguments.
75
76           Many of the methods which may be overridden in a subclass, or may
77           be passed as properties to the new constuctor such as in the
78           following:
79
80               CGI::Ex::Auth->new({
81                   get_pass_by_user => \&my_pass_sub,
82                   key_user         => 'my_user',
83                   key_pass         => 'my_pass',
84                   login_header     => \"<h1>My Login</h1>",
85               });
86
87           The following methods will look for properties of the same name.
88           Each of these will be described separately.
89
90               cgix
91               cleanup_user
92               cookie_domain
93               cookie_secure
94               cookie_path
95               cookies
96               expires_min
97               form
98               form_name
99               get_pass_by_user
100               js_uri_path
101               key_cookie
102               key_expires_min
103               key_logout
104               key_pass
105               key_redirect
106               key_save
107               key_time
108               key_user
109               key_verify
110               key_loggedout
111               bounce_on_logout
112               login_footer
113               login_form
114               login_header
115               login_script
116               login_template
117               handle_success
118               handle_failure
119               success_hook
120               failure_hook
121               logout_hook
122               no_cookie_verify
123               path_info
124               script_name
125               secure_hash_keys
126               template_args
127               template_include_path
128               template_obj
129               text_user
130               text_pass
131               text_save
132               text_submit
133               hide_save
134               use_base64
135               use_blowfish
136               use_crypt
137               use_plaintext
138               use_session_cookie
139               verify_token
140               verify_payload
141               verify_user
142
143       "generate_token"
144           Takes either an auth_data object from a auth_data returned by
145           verify_token, or a hashref of arguments.
146
147           Possible arguments are:
148
149               user           - the username we are generating the token for
150               real_pass      - the password of the user (if use_plaintext is false
151                                and use_crypt is false, the password can be an md5sum
152                                of the user's password)
153               use_blowfish   - indicates that we should use Crypt::Blowfish to protect
154                                the generated token.  The value of this argument is used
155                                as the key.  Default is false.
156               use_base64     - indicates that we should use Base64 encoding to protect
157                                the generated token.  Default is true.  Will not be
158                                used if use_blowfish is true.
159               use_plaintext  - indicates that we should keep the password in plaintext
160               use_crypt      - also indicates that we should keep the password in plaintext
161               expires_min    - says how many minutes until the generated token expires.
162                                Values <= 0 indicate to not ever expire.  Used only on cram
163                                types.
164               payload        - a payload that will be passed to generate_payload and then
165                                will be added to cram type tokens.  It cannot contain a /.
166               prefer_simple_cram
167                              - If the secure_hash_keys method returns keys, and it is a non-plaintext
168                                token, generate_token will create a secure_hash_cram.  Set
169                                this value to true to tell it to use a simple_cram.  This
170                                is generally only useful in testing.
171
172           The following are types of tokens that can be generated by
173           generate_token.  Each type includes pseudocode and a sample of a
174           generated that token.
175
176               plaintext:
177                   user         := "paul"
178                   real_pass    := "123qwe"
179                   token        := join("/", user, real_pass);
180
181                   use_base64   := 0
182                   token        == "paul/123qwe"
183
184                   use_base64   := 1
185                   token        == "cGF1bC8xMjNxd2U="
186
187                   use_blowfish := "foobarbaz"
188                   token        == "6da702975190f0fe98a746f0d6514683"
189
190                   Notes: This token will be used if either use_plaintext or use_crypt is set.
191                   The real_pass can also be the md5_sum of the password.  If real_pass is an md5_sum
192                   of the password but the get_pass_by_user hook returns the crypt'ed password, the
193                   token will not be able to be verified.
194
195               simple_cram:
196                   user        := "paul"
197                   real_pass   := "123qwe"
198                   server_time := 1148512991         # a time in seconds since epoch
199                   expires_min := 6 * 60
200                   payload     := "something"
201
202                   md5_pass    := md5_sum(real_pass) # if it isn't already a 32 digit md5 sum
203                   str         := join("/", user, server_time, expires_min, payload, md5_pass)
204                   md5_str     := md5(sum_str)
205                   token       := join("/", user, server_time, expires_min, payload, md5_str)
206
207                   use_base64  := 0
208                   token       == "paul/1148512991/360/something/16d0ba369a4c9781b5981eb89224ce30"
209
210                   use_base64  := 1
211                   token       == "cGF1bC8xMTQ4NTEyOTkxLzM2MC9zb21ldGhpbmcvMTZkMGJhMzY5YTRjOTc4MWI1OTgxZWI4OTIyNGNlMzA="
212
213                   Notes: use_blowfish is available as well
214
215               secure_hash_cram:
216                   user        := "paul"
217                   real_pass   := "123qwe"
218                   server_time := 1148514034         # a time in seconds since epoch
219                   expires_min := 6 * 60
220                   payload     := "something"
221                   secure_hash := ["aaaa", "bbbb", "cccc", "dddd"]
222                   rand1       := 3                  # int(rand(length(secure_hash)))
223                   rand2       := 39163              # int(rand(100000))
224
225                   md5_pass    := md5_sum(real_pass) # if it isn't already a 32 digit md5 sum
226
227                   sh_str1     := join(".", "sh", secure_hash[rand1], rand2)
228                   sh_str2     := join(".", "sh", rand1, rand2)
229                   str         := join("/", user, server_time, expires_min, payload, md5_pass, sh_str1)
230                   md5_str     := md5(sum_str)
231                   token       := join("/", user, server_time, expires_min, payload, md5_str, sh_str2)
232
233                   use_base64  := 0
234                   token       == "paul/1148514034/360/something/06db2914c9fd4e11499e0652bcf67dae/sh.3.39163"
235
236                   Notes: use_blowfish is available as well.  The secure_hash keys need to be set in the
237                   "secure_hash_keys" property of the CGI::Ex::Auth object.
238
239       "get_valid_auth"
240           Performs the core logic.  Returns an auth object on successful
241           login.  Returns false on errored login (with the details of the
242           error stored in $@).  If a false value is returned, execution of
243           the CGI should be halted.  get_valid_auth WILL NOT automatically
244           stop execution.
245
246             $auth->get_valid_auth || exit;
247
248           Optionally, the class and a list of arguments may be passed.  This
249           will create a new object using the passed arguments, and then run
250           get_valid_auth.
251
252             CGI::Ex::Auth->get_valid_auth({key_user => 'my_user'}) || exit;
253
254       "check_valid_auth"
255           Runs get_valid_auth with login_print and location_bounce set to do
256           nothing.  This allows for obtaining login data without forcing an
257           html login page to appear.
258
259       "login_print"
260           Called if login errored.  Defaults to printing a very basic (but
261           adequate) page loaded from login_template..
262
263           You will want to override it with a template from your own system.
264           The hook that is called will be passed the step to print (currently
265           only "get_login_info" and "no_cookies"), and a hash containing the
266           form variables as well as the following:
267
268       "login_hash_common"
269           Passed to the template swapped during login_print.
270
271               %$form,            # any keys passed to the login script
272               error              # The text "Login Failed" if a login occurred
273               login_data         # A login data object if they failed authentication.
274               key_user           # $self->key_user,        # the username fieldname
275               key_pass           # $self->key_pass,        # the password fieldname
276               key_time           # $self->key_time,        # the server time field name
277               key_save           # $self->key_save,        # the save password checkbox field name
278               key_redirect       # $self->key_redirect,    # the redirect fieldname
279               form_name          # $self->form_name,       # the name of the form
280               script_name        # $self->script_name,     # where the server will post back to
281               path_info          # $self->path_info,       # $ENV{PATH_INFO} if any
282               md5_js_path        # $self->js_uri_path ."/CGI/Ex/md5.js", # script for cramming
283               $self->key_user    # $data->{'user'},        # the username (if any)
284               $self->key_pass    # '',                     # intentional blankout
285               $self->key_time    # $self->server_time,     # the server's time
286               $self->key_expires_min # $self->expires_min  # how many minutes crams are valid
287               text_user          # $self->text_user        # template text Username:
288               text_pass          # $self->text_pass        # template text Password:
289               text_save          # $self->text_save        # template text Save Password ?
290               text_submit        # $self->text_submit      # template text Login
291               hide_save          # $self->hide_save        # 0
292
293       "bounce_on_logout"
294           Default 0.  If true, will location bounce to script returned by
295           logout_redirect passing the key key_logout.  If false, will simply
296           show the login screen.
297
298       "key_loggedout"
299           Key to bounce with in the form during a logout should
300           bounce_on_logout return true.  Default is "loggedout".
301
302       "key_logout"
303           If the form hash contains a true value in this field name, the
304           current user will be logged out.  Default is "cea_logout".
305
306       "key_cookie"
307           The name of the auth cookie.  Default is "cea_user".
308
309       "key_verify"
310           A field name used during a bounce to see if cookies exist.  Default
311           is "cea_verify".
312
313       "key_user"
314           The form field name used to pass the username.  Default is
315           "cea_user".
316
317       "key_pass"
318           The form field name used to pass the password.  Default is
319           "cea_pass".
320
321       "key_save"
322           Works in conjunction with key_expires_min.  If key_save is true,
323           then the cookie will be set to be saved for longer than the current
324           session (If it is a plaintext variety it will be given a 20 year
325           life rather than being a session cookie.  If it is a cram variety,
326           the expires_min portion of the cram will be set to -1).  If it is
327           set to false, the cookie will be available only for the session (If
328           it is a plaintext variety, the cookie will be session based and
329           will be removed on the next loggout.  If it is a cram variety then
330           the cookie will only be good for expires_min minutes.
331
332           Default is "cea_save".
333
334       "key_expires_min"
335           The name of the form field that contains how long cram type cookies
336           will be valid if key_save contains a false value.
337
338           Default key name is "cea_expires_min".  Default field value is 6 *
339           60 (six hours).
340
341           This value will have no effect when use_plaintext or use_crypt is
342           set.
343
344           A value of -1 means no expiration.
345
346       "failed_sleep"
347           Number of seconds to sleep if the passed tokens are invalid.  Does
348           not apply if validation failed because of expired tokens.  Default
349           value is 0.  Setting to 0 disables any sleeping.
350
351       "form_name"
352           The name of the html login form to attach the javascript to.
353           Default is "cea_form".
354
355       "verify_token"
356           This method verifies the token that was passed either via the form
357           or via cookies.  It will accept plaintext or crammed tokens (A
358           listing of the available algorithms for creating tokes is listed
359           below).  It also allows for armoring the token with base64
360           encoding, or using blowfish encryption.  A listing of creating
361           these tokens can be found under generate_token.
362
363       "parse_token"
364           Used by verify_token to remove armor from the passed tokens and
365           split the token into its parts.  Returns true if it was able to
366           parse the passed token.
367
368       "cleanup_user"
369           Called by verify_token.  Default is to do no modification.  Allows
370           for usernames to be lowercased, or canonized in some other way.
371           Should return the cleaned username.
372
373       "verify_user"
374           Called by verify_token.  Single argument is the username.  May or
375           may not be an initial check to see if the username is ok.  The
376           username will already be cleaned at this point.  Default return is
377           true.
378
379       "get_pass_by_user"
380           Called by verify_token.  Given the cleaned, verified username,
381           should return a valid password for the user.  It can always return
382           plaintext.  If use_crypt is enabled, it should return the crypted
383           password.  If use_plaintext and use_crypt are not enabled, it may
384           return the md5 sum of the password.
385
386              get_pass_by_user => sub {
387                  my ($auth_obj, $user) = @_;
388                  my $pass = $some_obj->get_pass({user => $user});
389                  return $pass;
390              }
391
392           Alternately, get_pass_by_user may return a hashref of data items
393           that will be added to the data object if the token is valid.  The
394           hashref must also contain a key named real_pass or password that
395           contains the password.  Note that keys passed back in the hashref
396           that are already in the data object will override those in the data
397           object.
398
399              get_pass_by_user => sub {
400                  my ($auth_obj, $user) = @_;
401                  my ($pass, $user_id) = $some_obj->get_pass({user => $user});
402                  return {
403                      password => $pass,
404                      user_id  => $user_id,
405                  };
406              }
407
408       "verify_password"
409           Called by verify_token.  Passed the password to check as well as
410           the auth data object.  Should return true if the password matches.
411           Default method can handle md5, crypt, cram, secure_hash_cram, and
412           plaintext (all of the default types supported by generate_token).
413           If a property named verify_password exists, it will be used and
414           called as a coderef rather than using the default method.
415
416       "verify_payload"
417           Called by verify_token.  Passed the password to check as well as
418           the auth data object.  Should return true if the payload is valid.
419           Default method returns true without performing any checks on the
420           payload.  If a property named verify_password exists, it will be
421           used and called as a coderef rather than using the default method.
422
423       "cgix"
424           Returns a CGI::Ex object.
425
426       "form"
427           A hash of passed form info.  Defaults to CGI::Ex::get_form.
428
429       "cookies"
430           The current cookies.  Defaults to CGI::Ex::get_cookies.
431
432       "login_template"
433           Should return either a template filename to use for the login
434           template, or it should return a reference to a string that contains
435           the template.  The contents will be used in login_print and passed
436           to the template engine.
437
438           Default login_template is the values of login_header, login_form,
439           login_script, and login_script concatenated together.
440
441           Values from login_hash_common will be passed to the template
442           engine, and will also be used to fill in the form.
443
444           The basic values are capable of handling most needs so long as
445           appropriate headers and css styles are used.
446
447       "login_header"
448           Should return a header to use in the default login_template.  The
449           default value will try to PROCESS a file called login_header.tt
450           that should be located in directory specified by the
451           template_include_path method.
452
453           It should ideally supply css styles that format the login_form as
454           desired.
455
456       "login_footer"
457           Same as login_header - but for the footer.  Will look for
458           login_footer.tt by default.
459
460       "login_form"
461           An html chunk that contains the necessary form fields to login the
462           user.  The basic chunk has a username text entry, password text
463           entry, save password checkbox, and submit button, and any hidden
464           fields necessary for logging in the user.
465
466       "login_script"
467           Contains javascript that will attach to the form from login_form.
468           This script is capable of taking the login_fields and creating an
469           md5 cram which prevents the password from being passed plaintext.
470
471       "text_user, text_pass, text_save"
472           The text items shown in the default login template.  The default
473           values are:
474
475               text_user  "Username:"
476               text_pass  "Password:"
477               text_save  "Save Password ?"
478
479       "disable_simple_cram"
480           Disables simple cram type from being an available type. Default is
481           false.  If set, then one of use_plaintext, use_crypt, or
482           secure_hash_keys should be set.  Setting this option allows for
483           payloads to be generated by the server only - otherwise a user who
484           understands the algorithm could generate a valid simple_cram cookie
485           with a custom payload.
486
487           Another option would be to only accept payloads from tokens if
488           use_blowfish is set and armor was equal to "blowfish."
489

LICENSE

491       This module may be distributed under the same terms as Perl itself.
492

AUTHORS

494       Paul Seamons <perl at seamons dot com>
495
496
497
498perl v5.30.1                      2020-01-29                  CGI::Ex::Auth(3)
Impressum