3 package Catalyst::Plugin::Authentication::Credential::Password;
9 use Catalyst::Exception ();
13 my ( $c, $user, $password ) = @_;
16 unless ( $user ||= $_->param("login")
18 || $_->param("username") )
21 "Can't login a user without a user object or user ID param");
25 unless ( $password ||= $_->param("password")
26 || $_->param("passwd")
27 || $_->param("pass") )
29 $c->log->debug("Can't login a user without a password");
34 unless ( Scalar::Util::blessed($user)
35 and $user->isa("Catalyst:::Plugin::Authentication::User") )
37 if ( my $user_obj = $c->get_user($user) ) {
41 $c->log->debug("User '$user' doesn't exist in the default store")
47 if ( $c->_check_password( $user, $password ) ) {
48 $c->set_authenticated($user);
49 $c->log->debug("Successfully authenticated user '$user'.")
55 "Failed to authenticate user '$user'. Reason: 'Incorrect password'"
63 my ( $c, $user, $password ) = @_;
65 if ( $user->supports(qw/password clear/) ) {
66 return $user->password eq $password;
68 elsif ( $user->supports(qw/password crypted/) ) {
69 my $crypted = $user->crypted_password;
70 return $crypted eq crypt( $password, $crypted );
72 elsif ( $user->supports(qw/password hashed/) ) {
74 my $d = Digest->new( $user->hash_algorithm );
75 $d->add( $user->password_pre_salt || '' );
77 $d->add( $user->password_post_salt || '' );
79 my $stored = $user->hashed_password;
80 my $computed = $d->digest;
82 return ( ( $computed eq $stored )
83 || ( unpack( "H*", $computed ) eq $stored ) );
85 elsif ( $user->supports(qw/password salted_hash/) ) {
86 require Crypt::SaltedHash;
89 $user->can("password_salt_len") ? $user->password_salt_len : 0;
91 return Crypt::SaltedHash->validate( $user->hashed_password, $password,
94 elsif ( $user->supports(qw/password self_check/) ) {
96 # while somewhat silly, this is to prevent code duplication
97 return $user->check_password($password);
101 Catalyst::Exception->throw(
102 "The user object $user does not support any "
103 . "known password authentication mechanism." );
115 Catalyst::Plugin::Authentication::Credential::Password - Authenticate a user
122 Authentication::Store::Foo
123 Authentication::Credential::Password
127 my ( $self, $c ) = @_;
129 $c->login( $c->req->param('username'), $c->req->param('password') );
134 This authentication credential checker takes a username (or userid) and a
135 password, and tries various methods of comparing a password based on what
136 the chosen store's user objects support:
140 =item clear text password
142 If the user has clear a clear text password it will be compared directly.
144 =item crypted password
146 If UNIX crypt hashed passwords are supported, they will be compared using
147 perl's builtin C<crypt> function.
149 =item hashed password
151 If the user object supports hashed passwords, they will be used in conjunction
160 =item login $username, $password
162 Try to log a user in.
164 C<$username> can be a string (e.g. retrieved from a form) or an object.
165 If the object is a L<Catalyst::Plugin::Authentication::User> it will be used
166 as is. Otherwise C<< $c->get_user >> is used to retrieve it.
168 C<$password> is a string.
170 If C<$username> or C<$password> are not provided, the query parameters
171 C<login>, C<user>, C<username> and C<password>, C<passwd>, C<pass> will
178 After the user is logged in, the user object for the current logged in user
179 can be retrieved from the context using the C<< $c->user >> method.
181 The current user can be logged out again by calling the C<< $c->logout >>
184 =head1 SUPPORTING THIS PLUGIN
186 For a User class to support credential verification using this plugin, it
187 needs to indicate what sort of password a given user supports
188 by implementing the C<supported_features> method in one or many of the
191 =head2 Clear Text Passwords
195 $user->supported_features(qw/password clear/);
203 Returns the user's clear text password as a string to be compared with C<eq>.
207 =head2 Crypted Passwords
211 $user->supported_features(qw/password crypted/);
217 =item crypted_password
219 Return's the user's crypted password as a string, with the salt as the first two chars.
223 =head2 Hashed Passwords
227 $user->supported_features(qw/password hashed/);
233 =item hashed_password
235 Return's the hash of the user's password as B<binary>.
239 Returns a string suitable for feeding into L<Digest/new>.
241 =item password_pre_salt
243 =item password_post_salt
245 Returns a string to be hashed before/after the user's password. Typically only
250 =head2 Crypt::SaltedHash Passwords
254 $user->supported_features(qw/password salted_hash/);
260 =item hashed_password
262 Returns the hash of the user's password as returned from L<Crypt-SaltedHash>->generate.
270 =item password_salt_len
272 Returns the length of salt used to generate the salted hash.