Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
CGI::Ex::Auth(3)      User Contributed Perl Documentation     CGI::Ex::Auth(3)

NAME
       CGI::Ex::Auth - Handle logins nicely.

SYNOPSIS
	   use CGI::Ex::Auth;

	   ### authorize the user
	   my $auth = CGI::Ex::Auth->get_valid_auth({
	       get_pass_by_user	=> \&get_pass_by_user,
	   });

	   sub get_pass_by_user	{
	       my $auth	= shift;
	       my $user	= shift;
	       my $pass	= some_way_of_getting_password($user);
	       return $pass;
	   }

	   ### OR - if you are using a OO based	CGI or Application

	   sub require_authentication {
	       my $self	= shift;

	       return $self->{'auth'} =	CGI::Ex::Auth->get_valid_auth({
		   get_pass_by_user => sub {
		       my ($auth, $user) = @_;
		       return $self->get_pass($user);
		   },
	       });
	   }

	   sub get_pass	{
	       my ($self, $user) = @_;
	       return $self->loopup_and_cache_pass($user);
	   }

DESCRIPTION
       CGI::Ex::Auth allows for	auto-expiring, safe and	easy web based logins.
       Auth uses javascript modules that perform MD5 hashing to	cram the
       password	on the client side before passing them through the internet.

       For the stored cookie you can choose to use simple cram mechanisms,
       secure hash cram	tokens,	auto expiring logins (not cookie based), and
       Crypt::Blowfish protection.  You	can also choose	to keep	passwords
       plaintext and to	use perl's crypt for testing passwords.	 Or you	can
       completely replace the cookie parsing/generating	and let	Auth handle
       requesting, setting, and	storing	the cookie.

       A theoretical downside to this module is	that it	does not use a session
       to preserve state so get_pass_by_user has to happen on every request
       (any authenticated area has to verify authentication each time -	unless
       the verify_token	method is completely overridden).  In theory you
       should be checking the password everytime a user	makes a	request	to
       make sure the password is still valid.  A definite plus is that you
       don't need to use a session if you don't	want to.  It is	up to the
       interested reader to add	caching	to the get_pass_by_user	method.

       In the end, the only truly secure login method is across	an https
       connection.  Any	connection across non-https (non-secure) is
       susceptible to cookie hijacking or tcp hijacking	- though the
       possibility of this is normally small and typically requires access to
       a machine somewhere in your TCP chain.  If in doubt - you should	try to
       use https - but even then you need to guard the logged in area against
       cross-site javascript exploits.	A discussion of	all security issues is
       far beyond the scope of this documentation.

METHODS
       "new"
	   Constructor.	 Takes a hashref of properties as arguments.

	   Many	of the methods which may be overridden in a subclass, or may
	   be passed as	properties to the new constuctor such as in the
	   following:

	       CGI::Ex::Auth->new({
		   get_pass_by_user => \&my_pass_sub,
		   key_user	    => 'my_user',
		   key_pass	    => 'my_pass',
		   login_header	    => \"<h1>My	Login</h1>",
	       });

	   The following methods will look for properties of the same name.
	   Each	of these will be described separately.

	       cgix
	       cleanup_user
	       cookie_domain
	       cookie_secure
	       cookie_path
	       cookies
	       expires_min
	       form
	       form_name
	       get_pass_by_user
	       js_uri_path
	       key_cookie
	       key_expires_min
	       key_logout
	       key_pass
	       key_redirect
	       key_save
	       key_time
	       key_user
	       key_verify
	       key_loggedout
	       bounce_on_logout
	       login_footer
	       login_form
	       login_header
	       login_script
	       login_template
	       handle_success
	       handle_failure
	       success_hook
	       failure_hook
	       logout_hook
	       no_cookie_verify
	       path_info
	       script_name
	       secure_hash_keys
	       template_args
	       template_include_path
	       template_obj
	       text_user
	       text_pass
	       text_save
	       text_submit
	       hide_save
	       use_base64
	       use_blowfish
	       use_crypt
	       use_plaintext
	       use_session_cookie
	       verify_token
	       verify_payload
	       verify_user

       "generate_token"
	   Takes either	an auth_data object from a auth_data returned by
	   verify_token, or a hashref of arguments.

	   Possible arguments are:

	       user	      -	the username we	are generating the token for
	       real_pass      -	the password of	the user (if use_plaintext is false
				and use_crypt is false,	the password can be an md5sum
				of the user's password)
	       use_blowfish   -	indicates that we should use Crypt::Blowfish to	protect
				the generated token.  The value	of this	argument is used
				as the key.  Default is	false.
	       use_base64     -	indicates that we should use Base64 encoding to	protect
				the generated token.  Default is true.	Will not be
				used if	use_blowfish is	true.
	       use_plaintext  -	indicates that we should keep the password in plaintext
	       use_crypt      -	also indicates that we should keep the password	in plaintext
	       expires_min    -	says how many minutes until the	generated token	expires.
				Values <= 0 indicate to	not ever expire.  Used only on cram
				types.
	       payload	      -	a payload that will be passed to generate_payload and then
				will be	added to cram type tokens.  It cannot contain a	/.
	       prefer_simple_cram
			      -	If the secure_hash_keys	method returns keys, and it is a non-plaintext
				token, generate_token will create a secure_hash_cram.  Set
				this value to true to tell it to use a simple_cram.  This
				is generally only useful in testing.

	   The following are types of tokens that can be generated by
	   generate_token.  Each type includes pseudocode and a	sample of a
	   generated that token.

	       plaintext:
		   user		:= "paul"
		   real_pass	:= "123qwe"
		   token	:= join("/", user, real_pass);

		   use_base64	:= 0
		   token	== "paul/123qwe"

		   use_base64	:= 1
		   token	== "cGF1bC8xMjNxd2U="

		   use_blowfish	:= "foobarbaz"
		   token	== "6da702975190f0fe98a746f0d6514683"

		   Notes: This token will be used if either use_plaintext or use_crypt is set.
		   The real_pass can also be the md5_sum of the	password.  If real_pass	is an md5_sum
		   of the password but the get_pass_by_user hook returns the crypt'ed password,	the
		   token will not be able to be	verified.

	       simple_cram:
		   user	       := "paul"
		   real_pass   := "123qwe"
		   server_time := 1148512991	     # a time in seconds since epoch
		   expires_min := 6 * 60
		   payload     := "something"

		   md5_pass    := md5_sum(real_pass) # if it isn't already a 32	digit md5 sum
		   str	       := join("/", user, server_time, expires_min, payload, md5_pass)
		   md5_str     := md5(sum_str)
		   token       := join("/", user, server_time, expires_min, payload, md5_str)

		   use_base64  := 0
		   token       == "paul/1148512991/360/something/16d0ba369a4c9781b5981eb89224ce30"

		   use_base64  := 1
		   token       == "cGF1bC8xMTQ4NTEyOTkxLzM2MC9zb21ldGhpbmcvMTZkMGJhMzY5YTRjOTc4MWI1OTgxZWI4OTIyNGNlMzA="

		   Notes: use_blowfish is available as well

	       secure_hash_cram:
		   user	       := "paul"
		   real_pass   := "123qwe"
		   server_time := 1148514034	     # a time in seconds since epoch
		   expires_min := 6 * 60
		   payload     := "something"
		   secure_hash := ["aaaa", "bbbb", "cccc", "dddd"]
		   rand1       := 3		     # int(rand(length(secure_hash)))
		   rand2       := 39163		     # int(rand(100000))

		   md5_pass    := md5_sum(real_pass) # if it isn't already a 32	digit md5 sum

		   sh_str1     := join(".", "sh", secure_hash[rand1], rand2)
		   sh_str2     := join(".", "sh", rand1, rand2)
		   str	       := join("/", user, server_time, expires_min, payload, md5_pass, sh_str1)
		   md5_str     := md5(sum_str)
		   token       := join("/", user, server_time, expires_min, payload, md5_str, sh_str2)

		   use_base64  := 0
		   token       == "paul/1148514034/360/something/06db2914c9fd4e11499e0652bcf67dae/sh.3.39163"

		   Notes: use_blowfish is available as well.  The secure_hash keys need	to be set in the
		   "secure_hash_keys" property of the CGI::Ex::Auth object.

       "get_valid_auth"
	   Performs the	core logic.  Returns an	auth object on successful
	   login.  Returns false on errored login (with	the details of the
	   error stored	in $@).	 If a false value is returned, execution of
	   the CGI should be halted.  get_valid_auth WILL NOT automatically
	   stop	execution.

	     $auth->get_valid_auth || exit;

	   Optionally, the class and a list of arguments may be	passed.	 This
	   will	create a new object using the passed arguments,	and then run
	   get_valid_auth.

	     CGI::Ex::Auth->get_valid_auth({key_user =>	'my_user'}) || exit;

       "check_valid_auth"
	   Runs	get_valid_auth with login_print	and location_bounce set	to do
	   nothing.  This allows for obtaining login data without forcing an
	   html	login page to appear.

       "login_print"
	   Called if login errored.  Defaults to printing a very basic (but
	   adequate) page loaded from login_template..

	   You will want to override it	with a template	from your own system.
	   The hook that is called will	be passed the step to print (currently
	   only	"get_login_info" and "no_cookies"), and	a hash containing the
	   form	variables as well as the following:

       "login_hash_common"
	   Passed to the template swapped during login_print.

	       %$form,		  # any	keys passed to the login script
	       error		  # The	text "Login Failed" if a login occurred
	       login_data	  # A login data object	if they	failed authentication.
	       key_user		  # $self->key_user,	    # the username fieldname
	       key_pass		  # $self->key_pass,	    # the password fieldname
	       key_time		  # $self->key_time,	    # the server time field name
	       key_save		  # $self->key_save,	    # the save password	checkbox field name
	       key_redirect	  # $self->key_redirect,    # the redirect fieldname
	       form_name	  # $self->form_name,	    # the name of the form
	       script_name	  # $self->script_name,	    # where the	server will post back to
	       path_info	  # $self->path_info,	    # $ENV{PATH_INFO} if any
	       md5_js_path	  # $self->js_uri_path ."/CGI/Ex/md5.js", # script for cramming
	       $self->key_user	  # $data->{'user'},	    # the username (if any)
	       $self->key_pass	  # '',			    # intentional blankout
	       $self->key_time	  # $self->server_time,	    # the server's time
	       $self->key_expires_min #	$self->expires_min  # how many minutes crams are valid
	       text_user	  # $self->text_user	    # template text Username:
	       text_pass	  # $self->text_pass	    # template text Password:
	       text_save	  # $self->text_save	    # template text Save Password ?
	       text_submit	  # $self->text_submit	    # template text Login
	       hide_save	  # $self->hide_save	    # 0

       "bounce_on_logout"
	   Default 0.  If true,	will location bounce to	script returned	by
	   logout_redirect passing the key key_logout.	If false, will simply
	   show	the login screen.

       "key_loggedout"
	   Key to bounce with in the form during a logout should
	   bounce_on_logout return true.  Default is "loggedout".

       "key_logout"
	   If the form hash contains a true value in this field	name, the
	   current user	will be	logged out.  Default is	"cea_logout".

       "key_cookie"
	   The name of the auth	cookie.	 Default is "cea_user".

       "key_verify"
	   A field name	used during a bounce to	see if cookies exist.  Default
	   is "cea_verify".

       "key_user"
	   The form field name used to pass the	username.  Default is
	   "cea_user".

       "key_pass"
	   The form field name used to pass the	password.  Default is
	   "cea_pass".

       "key_save"
	   Works in conjunction	with key_expires_min.  If key_save is true,
	   then	the cookie will	be set to be saved for longer than the current
	   session (If it is a plaintext variety it will be given a 20 year
	   life	rather than being a session cookie.  If	it is a	cram variety,
	   the expires_min portion of the cram will be set to -1).  If it is
	   set to false, the cookie will be available only for the session (If
	   it is a plaintext variety, the cookie will be session based and
	   will	be removed on the next loggout.	 If it is a cram variety then
	   the cookie will only	be good	for expires_min	minutes.

	   Default is "cea_save".

       "key_expires_min"
	   The name of the form	field that contains how	long cram type cookies
	   will	be valid if key_save contains a	false value.

	   Default key name is "cea_expires_min".  Default field value is 6 *
	   60 (six hours).

	   This	value will have	no effect when use_plaintext or	use_crypt is
	   set.

	   A value of -1 means no expiration.

       "failed_sleep"
	   Number of seconds to	sleep if the passed tokens are invalid.	 Does
	   not apply if	validation failed because of expired tokens.  Default
	   value is 0.	Setting	to 0 disables any sleeping.

       "form_name"
	   The name of the html	login form to attach the javascript to.
	   Default is "cea_form".

       "verify_token"
	   This	method verifies	the token that was passed either via the form
	   or via cookies.  It will accept plaintext or	crammed	tokens (A
	   listing of the available algorithms for creating tokes is listed
	   below).  It also allows for armoring	the token with base64
	   encoding, or	using blowfish encryption.  A listing of creating
	   these tokens	can be found under generate_token.

       "parse_token"
	   Used	by verify_token	to remove armor	from the passed	tokens and
	   split the token into	its parts.  Returns true if it was able	to
	   parse the passed token.

       "cleanup_user"
	   Called by verify_token.  Default is to do no	modification.  Allows
	   for usernames to be lowercased, or canonized	in some	other way.
	   Should return the cleaned username.

       "verify_user"
	   Called by verify_token.  Single argument is the username.  May or
	   may not be an initial check to see if the username is ok.  The
	   username will already be cleaned at this point.  Default return is
	   true.

       "get_pass_by_user"
	   Called by verify_token.  Given the cleaned, verified	username,
	   should return a valid password for the user.	 It can	always return
	   plaintext.  If use_crypt is enabled,	it should return the crypted
	   password.  If use_plaintext and use_crypt are not enabled, it may
	   return the md5 sum of the password.

	      get_pass_by_user => sub {
		  my ($auth_obj, $user)	= @_;
		  my $pass = $some_obj->get_pass({user => $user});
		  return $pass;
	      }

	   Alternately,	get_pass_by_user may return a hashref of data items
	   that	will be	added to the data object if the	token is valid.	 The
	   hashref must	also contain a key named real_pass or password that
	   contains the	password.  Note	that keys passed back in the hashref
	   that	are already in the data	object will override those in the data
	   object.

	      get_pass_by_user => sub {
		  my ($auth_obj, $user)	= @_;
		  my ($pass, $user_id) = $some_obj->get_pass({user => $user});
		  return {
		      password => $pass,
		      user_id  => $user_id,
		  };
	      }

       "verify_password"
	   Called by verify_token.  Passed the password	to check as well as
	   the auth data object.  Should return	true if	the password matches.
	   Default method can handle md5, crypt, cram, secure_hash_cram, and
	   plaintext (all of the default types supported by generate_token).
	   If a	property named verify_password exists, it will be used and
	   called as a coderef rather than using the default method.

       "verify_payload"
	   Called by verify_token.  Passed the password	to check as well as
	   the auth data object.  Should return	true if	the payload is valid.
	   Default method returns true without performing any checks on	the
	   payload.  If	a property named verify_password exists, it will be
	   used	and called as a	coderef	rather than using the default method.

       "cgix"
	   Returns a CGI::Ex object.

       "form"
	   A hash of passed form info.	Defaults to CGI::Ex::get_form.

       "cookies"
	   The current cookies.	 Defaults to CGI::Ex::get_cookies.

       "login_template"
	   Should return either	a template filename to use for the login
	   template, or	it should return a reference to	a string that contains
	   the template.  The contents will be used in login_print and passed
	   to the template engine.

	   Default login_template is the values	of login_header, login_form,
	   login_script, and login_script concatenated together.

	   Values from login_hash_common will be passed	to the template
	   engine, and will also be used to fill in the	form.

	   The basic values are	capable	of handling most needs so long as
	   appropriate headers and css styles are used.

       "login_header"
	   Should return a header to use in the	default	login_template.	 The
	   default value will try to PROCESS a file called login_header.tt
	   that	should be located in directory specified by the
	   template_include_path method.

	   It should ideally supply css	styles that format the login_form as
	   desired.

       "login_footer"
	   Same	as login_header	- but for the footer.  Will look for
	   login_footer.tt by default.

       "login_form"
	   An html chunk that contains the necessary form fields to login the
	   user.  The basic chunk has a	username text entry, password text
	   entry, save password	checkbox, and submit button, and any hidden
	   fields necessary for	logging	in the user.

       "login_script"
	   Contains javascript that will attach	to the form from login_form.
	   This	script is capable of taking the	login_fields and creating an
	   md5 cram which prevents the password	from being passed plaintext.

       "text_user, text_pass, text_save"
	   The text items shown	in the default login template.	The default
	   values are:

	       text_user  "Username:"
	       text_pass  "Password:"
	       text_save  "Save	Password ?"

       "disable_simple_cram"
	   Disables simple cram	type from being	an available type. Default is
	   false.  If set, then	one of use_plaintext, use_crypt, or
	   secure_hash_keys should be set.  Setting this option	allows for
	   payloads to be generated by the server only - otherwise a user who
	   understands the algorithm could generate a valid simple_cram	cookie
	   with	a custom payload.

	   Another option would	be to only accept payloads from	tokens if
	   use_blowfish	is set and armor was equal to "blowfish."

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

AUTHORS
       Paul Seamons <perl at seamons dot com>

perl v5.24.1			  2015-10-07		      CGI::Ex::Auth(3)

NAME | SYNOPSIS | DESCRIPTION | METHODS | LICENSE | AUTHORS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=CGI::Ex::Auth&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports>

home | help