1 package Catalyst::Authentication::Realm::Progressive;
7 use base 'Catalyst::Authentication::Realm';
11 Catalyst::Authentication::Realm::Progressive - Authenticate against multiple realms
15 This Realm allows an application to be built so that multiple realms are
16 supported and tried incrementally until a successful authentication.
18 A simple use case is a Temporary Password that looks and acts exactly as a
19 regular password. Without changing the authentication code, you can
20 authenticate against multiple realms.
24 If your application has multiple realms to authenticate, such as a temporary
25 password realm and a normal realm, you can configure the progressive realm as
26 the default, and configure it to iteratively call the temporary realm and then
30 'Plugin::Authentication' => {
31 default_realm => 'progressive',
34 class => 'Progressive',
35 realms => [ 'temp', 'normal' ],
36 # Modify the authinfo passed into authenticate by merging
37 # these hashes into the realm's authenticate call:
39 'local' => { 'realm' => 'normal' },
40 'temp' => { 'realm' => 'temp' },
46 password_field => 'secret',
47 password_type => 'hashed',
48 password_hash_type => 'SHA-1',
51 class => 'DBIx::Class',
52 user_class => 'Schema::Person::Identity',
59 password_field => 'secret',
60 password_type => 'hashed',
61 password_hash_type => 'SHA-1',
64 class => 'DBIx::Class',
65 user_class => 'Schema::Person::Identity',
73 Then, in your controller code, to attempt authentication against both realms
74 you just have to do a simple authenticate call:
76 if ( $c->authenticate({ id => $username, password => $password }) ) {
77 if ( $c->user->realm eq 'temp' ) {
78 # Force user to change password
88 An array reference consisting of each realm to attempt authentication against,
89 in the order listed. If the realm does not exist, calling authenticate will
94 A hash reference keyed by realm names, with values being hash references to
95 merge into the authinfo call that is subsequently passed into the realm's
96 authenticate method. This is useful if your store uses the same class for each
97 realm, separated by some other token (in the L<EXAMPLE> authinfo_mungesection,
98 the 'realm' is a column on C<Schema::Person::Identity> that will be either
99 'temp' or 'local', to ensure the query to fetch the user finds the right
100 Identity record for that realm.
108 This method iteratively calls each realm listed in the C<realms> configuration
109 key. It returns after the first successful authentication call is done.
114 my ( $self, $c, $authinfo ) = @_;
115 my $realms = $self->config->{realms};
116 carp "No realms to authenticate against, check configuration"
118 carp "Realms configuration must be an array reference"
119 unless ref $realms eq 'ARRAY';
120 foreach my $realm_name ( @$realms ) {
121 my $realm = $c->get_auth_realm( $realm_name );
122 carp "Unable to find realm: $realm_name, check configuration"
124 my $auth = { %$authinfo };
125 $auth->{realm} ||= $realm->name;
126 if ( my $info = $realm->config->{authinfo_munge}->{$realm->name} ) {
127 $auth = Catalyst::Utils::merge_hashes($auth, $info);
129 if ( my $obj = $realm->authenticate( $c, $auth ) ) {
130 $c->set_authenticated( $obj, $realm->name );
139 J. Shirley C<< <jshirley@cpan.org> >>
141 Jay Kuri C<< <jayk@cpan.org> >>
143 =head1 COPYRIGHT & LICENSE
145 Copyright (c) 2008 the aforementioned authors. All rights reserved. This program
146 is free software; you can redistribute it and/or modify it under the same terms