2 Catalyst::Plugin::Authentication - Infrastructure plugin for the
3 Catalyst authentication framework.
11 $c->authenticate({ username => 'myusername',
12 password => 'mypassword' });
13 my $age = $c->user->get('age');
17 The authentication plugin provides generic user support for Catalyst
18 apps. It is the basis for both authentication (checking the user is who
19 they claim to be), and authorization (allowing the user to do what the
20 system authorises them to do).
22 Using authentication is split into two parts. A Store is used to
23 actually store the user information, and can store any amount of data
24 related to the user. Credentials are used to verify users, using
25 information from the store, given data from the frontend. A Credential
26 and a Store are paired to form a 'Realm'. A Catalyst application using
27 the authentication framework must have at least one realm, and may have
30 To implement authentication in a Catalyst application you need to add
31 this module, and specify at least one realm in the configuration.
33 Authentication data can also be stored in a session, if the application
34 is using the Catalyst::Plugin::Session module.
36 NOTE in version 0.10 of this module, the interface to this module
37 changed. Please see "COMPATIBILITY ROUTINES" for more information.
40 The Authentication/Authorization Process
41 Web applications typically need to identify a user - to tell the user
42 apart from other users. This is usually done in order to display private
43 information that is only that user's business, or to limit access to the
44 application so that only certain entities can access certain parts.
46 This process is split up into several steps. First you ask the user to
47 identify themselves. At this point you can't be sure that the user is
48 really who they claim to be.
50 Then the user tells you who they are, and backs this claim with some
51 piece of information that only the real user could give you. For
52 example, a password is a secret that is known to both the user and you.
53 When the user tells you this password you can assume they're in on the
54 secret and can be trusted (ignore identity theft for now). Checking the
55 password, or any other proof is called credential verification.
57 By this time you know exactly who the user is - the user's identity is
58 authenticated. This is where this module's job stops, and your
59 application or other plugins step in.
61 The next logical step is authorization, the process of deciding what a
62 user is (or isn't) allowed to do. For example, say your users are split
63 into two main groups - regular users and administrators. You want to
64 verify that the currently logged in user is indeed an administrator
65 before performing the actions in an administrative part of your
66 application. These decisions may be made within your application code
67 using just the information available after authentication, or it may be
68 facilitated by a number of plugins.
70 The Components In This Framework
72 Configuration of the Catalyst::Plugin::Authentication framework is done
73 in terms of realms. In simplest terms, a realm is a pairing of a
74 Credential verifier and a User storage (Store) backend.
76 An application can have any number of Realms, each of which operates
77 independant of the others. Each realm has a name, which is used to
78 identify it as the target of an authentication request. This name can be
79 anything, such as 'users' or 'members'. One realm must be defined as the
80 default_realm, which is used when no realm name is specified. More
81 information about configuring realms is available in the configuration
85 When user input is transferred to the Catalyst application (typically
86 via form inputs) the application may pass this information into the
87 authentication system through the $c->authenticate() method. From there,
88 it is passed to the appropriate Credential verifier.
90 These plugins check the data, and ensure that it really proves the user
91 is who they claim to be.
94 The authentication data also identifies a user, and the Storage backend
95 modules use this data to locate and return a standardized
96 object-oriented representation of a user.
98 When a user is retrieved from a store it is not necessarily
99 authenticated. Credential verifiers accept a set of authentication data
100 and use this information to retrieve the user from the store they are
104 This plugin on its own is the glue, providing realm configuration,
105 session integration, and other goodness for the other plugins.
108 More layers of plugins can be stacked on top of the authentication code.
109 For example, Catalyst::Plugin::Session::PerUser provides an abstraction
110 of browser sessions that is more persistent per users.
111 Catalyst::Plugin::Authorization::Roles provides an accepted way to
112 separate and group users into categories, and then check which
113 categories the current user belongs to.
116 Let's say we were storing users in a simple perl hash. Users are
117 verified by supplying a password which is matched within the hash.
119 This means that our application will begin like this:
127 __PACKAGE__->config->{authentication} =
129 default_realm => 'members',
134 password_field => 'password',
135 password_type => 'clear'
141 password => "s00p3r",
143 roles => [qw/edit delete/],
146 password => "s3cr3t",
147 roles => [qw/comment/],
155 This tells the authentication plugin what realms are available, which
156 credential and store modules are used, and the configuration of each.
157 With this code loaded, we can now attempt to authenticate users.
159 To show an example of this, let's create an authentication controller:
161 package MyApp::Controller::Auth;
164 my ( $self, $c ) = @_;
166 if ( my $user = $c->req->param("user")
167 and my $password = $c->req->param("password") )
169 if ( $c->authenticate( { username => $user,
170 password => $password } ) ) {
171 $c->res->body( "hello " . $c->user->get("name") );
181 This code should be very readable. If all the necessary fields are
182 supplied, call the "authenticate" method from the controller. If it
183 succeeds the user is logged in.
185 The credential verifier will attempt to retrieve the user whose details
186 match the authentication information provided to $c->authenticate().
187 Once it fetches the user the password is checked and if it matches the
188 user will be authenticated and "$c->user" will contain the user object
189 retrieved from the store.
191 In the above case, the default realm is checked, but we could just as
192 easily check an alternate realm. If this were an admin login, for
193 example, we could authenticate on the admin realm by simply changing the
194 $c->authenticate() call:
196 if ( $c->authenticate( { username => $user,
197 password => $password }, 'admin' )l ) {
198 $c->res->body( "hello " . $c->user->get("name") );
201 Now suppose we want to restrict the ability to edit to a user with an
202 'editor' value of yes.
204 The restricted action might look like this:
207 my ( $self, $c ) = @_;
209 $c->detach("unauthorized")
210 unless $c->user_exists
211 and $c->user->get('editor') eq 'yes';
213 # do something restricted here
216 (Note that if you have multiple realms, you can use
217 $c->user_in_realm('realmname') in place of $c->user_exists(); This will
218 essentially perform the same verification as user_exists, with the added
219 requirement that if there is a user, it must have come from the realm
222 The above example is somewhat similar to role based access control.
223 Catalyst::Plugin::Authentication::Store::Minimal treats the roles field
224 as an array of role names. Let's leverage this. Add the role
225 authorization plugin:
233 my ( $self, $c ) = @_;
235 $c->detach("unauthorized") unless $c->check_roles("edit");
237 # do something restricted here
240 This is somewhat simpler and will work if you change your store, too,
241 since the role interface is consistent.
243 Let's say your app grew, and you now have 10000 users. It's no longer
244 efficient to maintain a hash of users, so you move this data to a
245 database. You can accomplish this simply by installing the DBIx::Class
246 Store and changing your config:
248 __PACKAGE__->config->{authentication} =
250 default_realm => 'members',
255 password_field => 'password',
256 password_type => 'clear'
259 class => 'DBIx::Class',
260 user_class => 'MyApp::Users',
261 role_column => 'roles'
267 The authentication system works behind the scenes to load your data from
268 the new source. The rest of your application is completely unchanged.
272 __PACKAGE__->config->{authentication} =
274 default_realm => 'members',
279 password_field => 'password',
280 password_type => 'clear'
283 class => 'DBIx::Class',
284 user_class => 'MyApp::Users',
285 role_column => 'roles'
291 password_field => 'password',
292 password_type => 'clear'
295 class => '+MyApp::Authentication::Store::NetAuth',
296 authserver => '192.168.10.17'
304 Whether or not to store the user's logged in state in the session,
305 if the application is also using Catalyst::Plugin::Session. This
306 value is set to true per default.
309 This defines which realm should be used as when no realm is provided
310 to methods that require a realm such as authenticate or find_user.
313 This contains the series of realm configurations you want to use for
314 your app. The only rule here is that there must be at least one. A
315 realm consists of a name, which is used to reference the realm, a
316 credential and a store.
318 Each realm config contains two hashes, one called 'credential' and
319 one called 'store', each of which provide configuration details to
320 the respective modules. The contents of these hashes is specific to
321 the module being used, with the exception of the 'class' element,
322 which tells the core Authentication module the classname to
325 The 'class' element follows the standard Catalyst mechanism of class
326 specification. If a class is prefixed with a +, it is assumed to be
327 a complete class name. Otherwise it is considered to be a portion of
328 the class name. For credentials, the classname 'Password', for
329 example, is expanded to
330 Catalyst::Plugin::Authentication::Credential::Password. For stores,
331 the classname 'storename' is expanded to:
332 Catalyst::Plugin::Authentication::Store::storename.
335 authenticate( $userinfo, $realm )
336 Attempts to authenticate the user using the information in the
337 $userinfo hash reference using the realm $realm. $realm may be
338 omitted, in which case the default realm is checked.
341 Returns the currently logged in user or undef if there is none.
344 Returns true if a user is logged in right now. The difference
345 between user_exists and user is that user_exists will return true if
346 a user is logged in, even if it has not been yet retrieved from the
347 storage backend. If you only need to know if the user is logged in,
348 depending on the storage mechanism this can be much more efficient.
350 user_in_realm ( $realm )
351 Works like user_exists, except that it only returns true if a user
352 is both logged in right now and was retrieved from the realm
356 Logs the user out, Deletes the currently logged in user from
357 $c->user and the session.
359 find_user( $userinfo, $realm )
360 Fetch a particular users details, matching the provided user info,
361 from the realm specified in $realm.
364 These methods are for Catalyst::Plugin::Authentication INTERNAL USE
365 only. Please do not use them in your own code, whether application or
366 credential / store modules. If you do, you will very likely get the
367 nasty shock of having to fix / rewrite your code when things change.
368 They are documented here only for reference.
370 set_authenticated ( $user, $realmname )
371 Marks a user as authenticated. This is called from within the
372 authenticate routine when a credential returns a user. $realmname
373 defaults to 'default'
375 auth_restore_user ( $user, $realmname )
376 Used to restore a user from the session. In most cases this is
377 called without arguments to restore the user via the session. Can be
378 called with arguments when restoring a user from some other method.
379 Currently not used in this way.
381 save_user_in_session ( $user, $realmname )
382 Used to save the user in a session. Saves $user in session, marked
383 as originating in $realmname. Both arguments are required.
386 Returns a hashref containing realmname -> realm instance pairs.
387 Realm instances contain an instantiated store and credential object
388 as the 'store' and 'credential' elements, respectively
390 get_auth_realm ( $realmname )
391 Retrieves the realm instance for the realmname provided.
396 This list might not be up to date. Below are modules known to work with
397 the updated API of 0.10 and are therefore compatible with realms.
399 User Storage Backends
400 Catalyst::Plugin::Authentication::Store::Minimal,
401 Catalyst::Plugin::Authentication::Store::DBIx::Class,
403 Credential verification
404 Catalyst::Plugin::Authentication::Credential::Password,
407 Catalyst::Plugin::Authorization::ACL,
408 Catalyst::Plugin::Authorization::Roles
410 Internals Documentation
411 Catalyst::Plugin::Authentication::Internals
414 Catalyst::Plugin::Session, Catalyst::Plugin::Session::PerUser
417 This module along with its sub plugins deprecate a great number of other
418 modules. These include Catalyst::Plugin::Authentication::Simple,
419 Catalyst::Plugin::Authentication::CDBI.
421 At the time of writing these plugins have not yet been replaced or
422 updated, but should be eventually:
423 Catalyst::Plugin::Authentication::OpenID,
424 Catalyst::Plugin::Authentication::LDAP,
425 Catalyst::Plugin::Authentication::CDBI::Basic,
426 Catalyst::Plugin::Authentication::Basic::Remote.
429 The realms based configuration and functionality of the 0.10 update of
430 Catalyst::Plugin::Authentication required a change in the API used by
431 credentials and stores. It has a compatibility mode which allows use of
432 modules that have not yet been updated. This, however, completely mimics
433 the older api and disables the new realm-based features. In other words
434 you can not mix the older credential and store modules with realms, or
435 realm-based configs. The changes required to update modules are
436 relatively minor and are covered in
437 Catalyst::Plugin::Authentication::Internals. We hope that most modules
438 will move to the compatible list above very quickly.
440 COMPATIBILITY ROUTINES
441 In version 0.10 of Catalyst::Plugin::Authentication, the API changed.
442 For app developers, this change is fairly minor, but for Credential and
443 Store authors, the changes are significant.
445 Please see the documentation in version 0.09 of
446 Catalyst::Plugin::Authentication for a better understanding of how the
449 The items below are still present in the plugin, though using them is
450 deprecated. They remain only as a transition tool, for those sites which
451 can not yet be upgraded to use the new system due to local
452 customizations or use of Credential / Store modules that have not yet
453 been updated to work with the new API.
455 These routines should not be used in any application using realms
456 functionality or any of the methods described above. These are for
457 reference purposes only.
460 This method is used to initiate authentication and user retrieval.
461 Technically this is part of the old Password credential module and
462 it still resides in the Password class. It is included here for
466 Return the store whose name is 'default'.
468 This is set to "$c->config->{authentication}{store}" if that value
469 exists, or by using a Store plugin:
471 # load the Minimal authentication store.
472 use Catalyst qw/Authentication Authentication::Store::Minimal/;
474 Sets the default store to
475 Catalyst::Plugin::Authentication::Store::Minimal.
478 Return the store whose name is $name.
480 get_auth_store_name $store
481 Return the name of the store $store.
484 A hash keyed by name, with the stores registered in the app.
486 register_auth_stores %stores_by_name
487 Register stores into the application.
490 Yuval Kogman, "nothingmuch@woobling.org"
492 Jay Kuri, "jayk@cpan.org"
499 Copyright (c) 2005 the aforementioned authors. All rights
500 reserved. This program is free software; you can redistribute
501 it and/or modify it under the same terms as Perl itself.