[Catalyst-commits] r6543 - in trunk/Catalyst-Plugin-Authentication:
. lib/Catalyst/Plugin lib/Catalyst/Plugin/Authentication/Store
lib/Catalyst/Plugin/Authentication/Store/Minimal
matthewt at dev.catalyst.perl.org
matthewt at dev.catalyst.perl.org
Tue Jul 17 17:57:45 GMT 2007
Author: matthewt
Date: 2007-07-17 17:57:45 +0100 (Tue, 17 Jul 2007)
New Revision: 6543
Modified:
trunk/Catalyst-Plugin-Authentication/
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm
trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm
Log:
r33941 at cain (orig r5491): jayk | 2006-11-11 00:00:03 +0000
mostly doc fixes and a little Minimal Bug fix involving the hash passed in.
Property changes on: trunk/Catalyst-Plugin-Authentication
___________________________________________________________________
Name: svk:merge
- 4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-Plugin-Authentication:5490
+ 4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-Plugin-Authentication:5491
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm 2007-07-17 16:57:39 UTC (rev 6542)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal/Backend.pm 2007-07-17 16:57:45 UTC (rev 6543)
@@ -11,7 +11,7 @@
sub new {
my ( $class, $config, $app) = @_;
- bless { hash => $config }, $class;
+ bless { hash => $config->{'users'} }, $class;
}
sub from_session {
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm 2007-07-17 16:57:39 UTC (rev 6542)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication/Store/Minimal.pm 2007-07-17 16:57:45 UTC (rev 6543)
@@ -12,7 +12,7 @@
$c->default_auth_store(
Catalyst::Plugin::Authentication::Store::Minimal::Backend->new(
- $c->config->{authentication}{users}, $c
+ $c->config->{authentication}, $c
)
);
Modified: trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm
===================================================================
--- trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm 2007-07-17 16:57:39 UTC (rev 6542)
+++ trunk/Catalyst-Plugin-Authentication/lib/Catalyst/Plugin/Authentication.pm 2007-07-17 16:57:45 UTC (rev 6543)
@@ -435,8 +435,8 @@
Using authentication is split into two parts. A Store is used to actually
store the user information, and can store any amount of data related to
the user. Multiple stores can be accessed from within one application.
-Credentials are used to verify users, using the store, given data from
-the frontend.
+Credentials are used to verify users, using information from the store,
+given data from the frontend.
To implement authentication in a Catalyst application you need to add this
module, plus at least one store and one credential module.
@@ -475,28 +475,42 @@
=head2 The Components In This Framework
+=head3 Realms
+
+Configuration of the Catalyst::Plugin::Authentication framework is done in
+terms of realms. In simplest terms, a realm is a pairing of a Credential
+verifier and a User storage (Store) backend.
+
+An application can have any number of Realms, each of which operates
+independant of the others. Each realm has a name, which is used to identify it
+as the target of an authentication request. This name can be anything, such as
+'users' or 'members'. One realm must be defined as the default_realm, which is
+used when no realm name is specified. More about this in the configuration
+section.
+
=head3 Credential Verifiers
When user input is transferred to the L<Catalyst> application (typically via
-form inputs) this data then enters the authentication framework through these
-plugins.
+form inputs) this authentication data then enters the authentication framework
+through the $c->authenticate() routine. From there, it is passed to the
+appropriate Credential verifier.
These plugins check the data, and ensure that it really proves the user is who
they claim to be.
=head3 Storage Backends
-The credentials also identify a user, and this family of modules is supposed to
-take this identification data and return a standardized object oriented
-representation of users.
+The authentication data also identify a user, and the Storage Backend modules
+use this data to locate and return a standardized object-oriented
+representation of a user.
When a user is retrieved from a store it is not necessarily authenticated.
-Credential verifiers can either accept a user object, or fetch the object
-themselves from the default store.
+Credential verifiers accept a set of authentication data and use this
+information to retrieve the user from the store they are paired with.
=head3 The Core Plugin
-This plugin on its own is the glue, providing store registration, session
+This plugin on its own is the glue, providing realm configuration, session
integration, and other goodness for the other plugins.
=head3 Other Plugins
@@ -510,7 +524,7 @@
=head1 EXAMPLE
-Let's say we were storing users in an Apache style htpasswd file. Users are
+Let's say we were storing users in an simple perl hash. Users are
stored in that file, with a hashed password and some extra comments. Users are
verified by supplying a password which is matched with the file.
@@ -520,19 +534,41 @@
use Catalyst qw/
Authentication
- Authentication::Credential::Password
- Authentication::Store::Htpasswd
/;
- __PACKAGE__->config->{authentication}{htpasswd} = "passwdfile";
+ __PACKAGE__->config->{authentication} =
+ {
+ default_realm => 'members',
+ realms => {
+ members => {
+ credential => {
+ class => 'Password'
+ },
+ store => {
+ class => 'Minimal',
+ users = {
+ bob => {
+ password => "s3cr3t",
+ editor => 'yes',
+ roles => [qw/edit delete/],
+ },
+ william => {
+ password => "s00p3r",
+ roles => [qw/comment/],
+ }
+ }
+ }
+ }
+ }
+ };
+
-This loads the appropriate methods and also sets the htpasswd store as the
-default store.
+This tells the authentication plugin what realms are available, which credential
+and store modules are used, and the configuration of each.
-So, now that we have the code loaded we need to get data from the user into the
-credential verifier.
+With this code loaded, we can now attempt to authenticate users.
-Let's create an authentication controller:
+To show an example of this, let's create an authentication controller:
package MyApp::Controller::Auth;
@@ -542,8 +578,9 @@
if ( my $user = $c->req->param("user")
and my $password = $c->req->param("password") )
{
- if ( $c->login( $user, $password ) ) {
- $c->res->body( "hello " . $c->user->name );
+ if ( $c->authenticate( { username => $user,
+ password => $password } ) ) {
+ $c->res->body( "hello " . $c->user->get("name") );
} else {
# login incorrect
}
@@ -554,60 +591,55 @@
}
This code should be very readable. If all the necessary fields are supplied,
-call the L<Authentication::Credential::Password/login> method on the
-controller. If that succeeds the user is logged in.
+call the L<Catalyst::Plugin::Authentication/authenticate> method in the
+controller. If it succeeds the user is logged in.
-It could be simplified though:
+The credential verifier will attempt to retrieve the user whose details match
+the authentication information provided to $c->authenticate(). Once it fetches
+the user the password is checked and if it matches the user will be
+'authenticated' and C<< $c->user >> will contain the user object retrieved
+from the store.
- sub login : Local {
- my ( $self, $c ) = @_;
+In the above case, the default realm is checked, but we could just as easily
+check an alternate realm. If this were an admin login, for example, we could
+authenticate on the admin realm by simply changing the $c->authenticate()
+call:
- if ( $c->login ) {
- ...
- }
- }
+ if ( $c->authenticate( { username => $user,
+ password => $password }, 'admin' )l ) {
+ $c->res->body( "hello " . $c->user->get("name") );
+ } ...
-Since the C<login> method knows how to find logically named parameters on its
-own.
-The credential verifier will ask the default store to get the user whose ID is
-the user parameter. In this case the default store is the htpasswd one. Once it
-fetches the user from the store the password is checked and if it's OK
-C<< $c->user >> will contain the user object returned from the htpasswd store.
+Now suppose we want to restrict the ability to edit to a user with 'edit'
+in it's roles list.
-We can also pass a user object to the credential verifier manually, if we have
-several stores per app. This is discussed in
-L<Catalyst::Plugin::Authentication::Store>.
+The restricted action might look like this:
-Now imagine each admin user has a comment set in the htpasswd file saying
-"admin".
-
-A restricted action might look like this:
-
- sub restricted : Local {
+ sub edit : Local {
my ( $self, $c ) = @_;
$c->detach("unauthorized")
unless $c->user_exists
- and $c->user->extra_info() eq "admin";
+ and $c->user->get('editor') == 'yes';
# do something restricted here
}
This is somewhat similar to role based access control.
-L<Catalyst::Plugin::Authentication::Store::Htpasswd> treats the extra info
-field as a comma separated list of roles if it's treated that way. Let's
-leverage this. Add the role authorization plugin:
+L<Catalyst::Plugin::Authentication::Store::Minimal> treats the roles field as
+an array of role names. Let's leverage this. Add the role authorization
+plugin:
use Catalyst qw/
...
Authorization::Roles
/;
- sub restricted : Local {
+ sub edit : Local {
my ( $self, $c ) = @_;
- $c->detach("unauthorized") unless $c->check_roles("admin");
+ $c->detach("unauthorized") unless $c->check_roles("edit");
# do something restricted here
}
@@ -615,6 +647,8 @@
This is somewhat simpler and will work if you change your store, too, since the
role interface is consistent.
+ .... This is the end of the updated documentation for v0.10 - more soon ....
+
Let's say your app grew, and you now have 10000 users. It's no longer efficient
to maintain an htpasswd file, so you move this data to a database.
More information about the Catalyst-commits
mailing list