minor updates
[catagits/Catalyst-Plugin-Authentication.git] / lib / Catalyst / Plugin / Authentication / Internals.pod
CommitLineData
649de93b 1
2=head1 NAME
3
4Catalyst::Plugin::Authentication::Internals - All about authentication Stores and Credentials
5
6=head1 INTRODUCTION
7
8L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication> provides
9a standard authentication interface to application developers using the
10Catalyst framework. It is designed to allow application developers to use
11various methods of user storage and credential verification. It is also
12designed to provide for minimal change to the application when switching
13between different storage and credential verification methods.
14
15While L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>
16provides the interface to the application developer, the actual work of
17verifying the credentials and retrieving users is delegated to separate
18modules. These modules are called B<Credentials> and storage backends, or
19B<Stores>, respectively. For authentication to function there must be at least
20one credential and one storage backend. A pairing of a store and a credential
21is referred to as a B<Realm>. There may be any number of realms defined for an
22application, though most applications will not require more than one or two.
23
24The details of using this module can be found in the
25L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>
26documentation.
27
28What follows is an explanation of how the module functions internally and what
29is required to implement a credential or a store.
30
31=head1 OVERVIEW
32
33There are two main entry points you need to be aware of when writing a store
34or credential module. The first is initialization and the second is during the
35actual call to the Catalyst application's authenticate method.
36
37=head2 INITIALIZATION
38
39When the authentication module is loaded, it reads it's configuration to
40determine the realms to set up for the application and which realm is to be
41the default. For each realm defined in the application's config,
42L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>
43instantiates both a new credential object and a new store object. See below
44for the details of how credentials and stores are instantiated.
45
46 NOTE: The instances created will remain active throughout the entire
47 lifetime of the application, and so should be relatively lightweight.
48 Care should be taken to ensure that they do not grow, or retain
49 information per request, because they will be involved in each
50 authentication request and could therefore substantially
51 hurt memory consumption over time.
52
53=head2 AUTHENTICATION
54
55When C<$c-E<gt>authenticate()> is called from within an application, the
56objects created in the initialization process come into play.
57C<$c-E<gt>authenticate()> takes two arguments. The first is a hash reference
58containing all the information available about the user. This will be used to
59locate the user in the store and verify the user's credentials. The second
60argument is the realm to authenticate against. If the second argument is
61omitted, the default realm is assumed.
62
63The main authentication module then locates the credential and store objects
64for the realm specified and calls the credential object's C<authenticate()>
65method. It provides three arguments, first the application object, or C<$c>,
66then a reference to the store object, and finally the hashref provided in the
67C<$c-E<gt>authenticate> call. The main authentication module expects the
68return value to be a reference to a user object upon successful
69authentication. If it receives anything aside from a reference, it is
70considered to be an authentication failure. Upon success, the returned user is
71marked as authenticated and the application can act accordingly, using
72C<$c-E<gt>user> to access the authenticated user, etc.
73
74Astute readers will note that the main
75L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication> module
76does not interact with the store in any way, save for passing a reference to
77it to the credential. This is correct. The credential object is responsible
78for obtaining the user from the provided store using information from the
79userinfo hashref and/or data obtained during the credential verification
80process.
81
82=head1 WRITING A STORE
83
84There are two parts to an authentication store, the backend and the user object.
85
86=head2 STORAGE BACKEND
87
88Writing a storage backend is actually quite simple. There are only five methods
89that must be implemented. They are:
90
91 new() - instantiates the store object
92 find_user() - locates a user using data contained in the hashref
93 for_session() - prepares a user to be stored in the session
94 from_session() - does any restoration required when obtaining a user from the session
95 user_supports() - provides information about what the user object supports
96
97=head3 STORE METHODS
98
99=over 4
100
101=item new( $config, $app )
102
103The C<new()> method is called only once, during the setup process of
104L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>. The
105first argument, C<$config>, is a hash reference containing the configuration
106information for the store module. The second argument is a reference to the
107Catalyst application.
108
109 Note that when new() is called, Catalyst has not yet loaded the various
110 controller and model classes, nor is it definite that other plugins have
111 been loaded, so your new() method must not rely on any of those being
112 present. If any of this is required for your store to function, you should
113 defer that part of initialization until the first method call.
4b69b736 114
649de93b 115The C<new()> method should return a blessed reference to your store object.
116
117=item find_user( $authinfo, $c )
118
119This is the workhorse of any authentication store. It's job is to take the
120information provided to it via the C<$authinfo> hashref and locate the user
121that matches it. It should return a reference to a user object. A return value
122of anything else is considered to mean no user was found that matched the
123information provided.
124
125How C<find_user()> accomplishes it's job is entirely up to you, the author, as
126is what $authinfo is required to contain. Many stores will simply use a
127username element in $authinfo to locate the user, but more advanced functionality
128is possible and you may bend the $authinfo to your needs. Be aware, however, that
129both Credentials and Stores work with the same $authinfo hash, so take care to
130avoid overlapping element names.
131
132Please note that this routine may be called numerous times in various
133circumstances, and that a successful match for a user here does B<NOT>
134necessarily constitute successful authentication. Your store class should
135never assume this and in most cases C<$c> B<should not be modified> by your
136store object.
137
138=item for_session( $c, $user )
139
140This method is responsible for preparing a user object for storage in the session.
141It should return information that can be placed in the session and later used to
142restore a user object (using the C<from_session()> method). It should therefore
143ensure that whatever information provided can be used by the C<from_session()>
144method to locate the unique user being saved. Note that there is no guarantee
145that the same Catalyst instance will receive both the C<for_session()> and
146C<from_session()> calls. You should take care to provide information that can
147be used to restore a user, regardless of the current state of the application.
148A good rule of thumb is that if C<from_session()> can revive the user with the
149given information even if the Catalyst application has just started up, you are
150in good shape.
151
152=item from_session( $c, $frozenuser )
153
154This method is called whenever a user is being restored from the session.
155C<$frozenuser> contains the information that was stored in the session for the user.
156This will under normal circumstances be the exact data your store returned from
157the previous call to C<for_session()>. C<from_session()> should return a valid
158user object.
159
160=item user_supports( $feature, ... )
161
162This method allows credentials and other objects to inquire as to what the
163underlying user object is capable of. This is pretty-well free-form and the
164main purpose is to allow graceful integration with credentials and
165applications that may provide advanced functionality based on whether the
166underlying user object can do certain things. In most cases you will want to
167pass this directly to the underlying user class' C<supports> method. Note that
168this is used as a B<class> method against the user class and therefore must
169be able to function without an instantiated user object.
170
171=back
172
173=head2 USER OBJECT
174
175The user object is an important piece of your store module. It will be the
176part of the system that the application developer will interact with most. As
177such, the API for the user object is very rigid. All user objects B<MUST>
178inherit from
179L<Catalyst::Plugin::Authentication::User|Catalyst::Plugin::Authentication::User>.
180
181=head3 USER METHODS
182
183The routines required by the
184L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication> plugin
185are below. Note that of these, only get_object is strictly required, as the
186L<Catalyst::Plugin::Authentication::User|Catalyst::Plugin::Authentication::User>
187base class contains reasonable implementations of the rest. If you do choose
4b69b736 188to implement only the C<get_object()> routine, please read the base class code
189and documentation so that you fully understand how the other routines will be
649de93b 190implemented for you.
191
192Also, your user object can implement whatever additional methods you require
193to provide the functionality you need. So long as the below are implemented,
194and you don't overlap the base class' methods with incompatible routines, you
195should experience no problems.
196
197=over 4
198
199=item id( )
200
201The C<id()> method should return a unique id (scalar) that can be used to
202retreive this user from the store. Often this will be provided to the store's
203C<find_user()> routine as C<id =E<gt> $user-E<gt>id> so you should ensure that your
204store's C<find_user()> can cope with that.
205
206=item supports_features( )
207
208This method should return a hashref of 'extra' features supported. This is for
209more flexible integration with some Credentials / applications. It is not
210required that you support anything, and returning C<undef> is perfectly
211acceptable and in most cases what you will do.
212
213=item get( $fieldname )
214
215This method should return the value of the field matching fieldname provided,
216or undef if there is no field matching that fieldname. In most cases this will
217access the underlying storage mechanism for the user data and return the
218information. This is used as a standard method of accessing an authenticated
219user's data, and MUST be implemented by all user objects.
220
221 Note: There is no equivalent 'set' method. Each user class is likely
222 to vary greatly in how data must be saved and it is therefore impractical to
223 try to provide a standard way of accomplishing it. When an application
224 developer needs to save data, they should obtain the underlying object / data
225 by calling get_object, and work with it directly.
226
227
228=item get_object( )
229
230This method returns the underlying user object. If your user object is backed
231by another object class, this method should return that underlying object.
232This allows the application developer to obtain an editable object. Generally
233speaking this will only be done by developers who know what they are doing and
234require advanced functionality which is either unforeseen or inconsistent
235across user classes. If your object is not backed by another class, or you
236need to provide additional intermediate functionality, it is perfectly
237reasonable to return C<$self>.
238
239=back
240
241
4b69b736 242=head1 WRITING A CREDENTIAL
243
244There are two parts to an authentication store, the backend and the user object.
245
246=head2 STORAGE BACKEND
649de93b 247... Documentation fairy fell asleep here.