5 CGI::Auth::Flexible - web authentication optionally using cookies
9 my $verifier = CGI::Auth::Flexible->new_verifier(setting => value,...);
10 my $authreq = $verifier->new_request($cgi_query_object);
13 $authreq->check_ok() or return;
15 # sophisticated applications
16 my $divert_kind = $authreq->check_divert();
17 if ($divert_kind) { ... print diversion page and quit ... }
19 # while handling the request
20 $user = $authreq->get_username();
21 $authreq->check_mutate();
25 CGI::Auth::Flexible is a library which you can use to add a
26 forms/cookie-based login facility to a Perl web application.
28 CGI::Auth::Flexible doesn't interfere with your application's URL path
29 namespace and just needs a few (configurable) form parameter and
30 cookie name(s) for its own use. It tries to avoid making assumptions
31 about the implementation structure of your application.
33 Because CGI::Auth::Flexible is licenced under the AGPLv3, you will
34 probably need to provide a facility to allow users (even ones not
35 logged in) to download the source code for your web app. Conveniently
36 by default CGI::Auth::Flexible provides (for pure Perl webapps) a
37 mechanism for users to get the source.
39 CGI::Auth::Flexible is designed to try to stop you accidentally
40 granting access by misunderstanding the API. (Also it, of course,
41 guards against cross-site scripting.) You do need to make sure to
42 call CGI::Auth::Flexible before answering AJAX requests as well as
43 before generating HTML pages, of course, and to call it in every
44 entrypoint to your system.
48 As a minimum you need to do all of the things on this checklist, where
49 applicable. The items marked SECURITY are the ones that you might
50 forget: without them your application may appear to work, but will be
57 Call C<new_verifier> (once at application startup)
61 Call C<new_request> (once per request)
65 B<SECURITY>: Call C<check_ok> or C<check_divert> on every request, and
66 honour the return value.
70 If you're using C<check_ok>, implement either the
71 C<username_password_error> or C<login_ok> hook.
75 Call C<get_username> when you need to know who's logged in.
79 B<SECURITY>: Call C<check_mutate> or C<mutate_ok>, if you specified
80 C<promise_check_mutate>.
84 B<SECURITY>: Call C<check_nonpage> for every request which is not a page load
85 (if your application has any of those).
89 When generating URLs and forms (including AJAX requests), include the
90 hidden form parameter using C<secret_hidden_val> or
91 C<secret_hidden_html> when appropriate (see below).
95 B<SECURITY>: If you do not override the source provision facility (see
96 L</SOURCE CODE DOWNLOAD>), check that the assumptions it makes aren't
97 going to leak security-critical data.
101 These points will now be covered in more detail.
103 =head2 INITIALISATION
105 Your application should, on startup (eg, when it is loaded by
107 C<< $verifier = CGI::Auth::Flexible->new_verifier(settings...) >>.
108 This call can be expensive and is best amortised.
110 The resulting verifier object can be used to process individual
111 requests, in each case with
112 C<< $authreq = CGI::Auth::Flexible->new_request($cgi_query) >>.
114 =head2 CHECKING AND RESPONSE GENERATION
116 If the user is logged in, your application is to handle the request.
117 Otherwise, the user needs to be presented with a login form or error
118 message, as appropriate. CGI::Auth::Flexible provides two alternative
121 =head3 Simple applications
123 The simplist usage is to call C<< $request->check_ok() >> which will
124 check the user's authentication. If the user is not logged in it will
125 generate a login form (or redirection or other appropriate page) and
126 return false; your application should not then processing that request
127 any further. If the user is logged in it will return true.
129 Various hooks are provided to customise the responses generated by
132 After C<check_ok> returns true you should go ahead and process the
133 request; you can use C<< $request->get_username >> to find out which
134 user the request came from.
136 =head2 Sophisticated applications
138 If you want to handle the control flow and to generate login forms,
139 redirections, etc., yourself, you can say
140 C<< $divert = $request->check_divert >>. This returns undef if
141 the user is logged in, or I<divert spec> if some kind of login
142 page or diversion should be generated.
146 =head2 MUTATING OPERATIONS AND EXTERNAL LINKS
148 =head3 Mutation-ignorant applications
150 By default CGI::Auth::Flexible does not permit external links into
151 your site. All GET requests give a "click to continue" page which
152 submits a form which loads your app's main page. In this
153 configuration all your application's forms and AJAX requests should
154 use C<POST>. This restriction arises from complicated deficiencies
155 in the web's security architecture.
157 Such applications are also not able to provide user-specific CSS
158 stylesheets, javascript, favicons, etc.
160 =head3 Mutation-aware applications
162 The alternative is for your application to always make a special check
163 when the incoming request is going to do some kind of action (such as
164 modifying the user's setup, purchasing goods, or whatever) rather than
165 just retrieve and/or display information. We term such requests
168 Then non-mutating pages can be linked to from other, untrustworthy,
171 To support external links, and C<GET> requests, pass
172 C<< promise_check_mutate => 1 >> in I<settings>, and then call
173 C<< $authreq->check_mutate() >> before taking any actions. If the
174 incoming request is not suitable then C<< $authreq->check_mutate() >>
177 There have to be no mutating C<GET> requests in your application (but
178 you shouldn't have any of those anyway); if there are, they won't
179 work. (CGI::Auth::Flexible will spot them and cause them to fail,
180 rather than allow them to be insecure.)
182 =head2 GENERATING URLS, FORMS AND AJAX QUERIES
184 When you generate a URL, C<POST> form or AJAX request you may need to
185 include a secret hidden form parameter for the benefit of
186 CGI::Auth::Generic. This form parameter will be checked by
187 C<check_ok>/C<check_divert> and should be ignored by your application.
189 By default the hidden parameter is called C<caf_assochash>.
191 After calling C<check_ok> or C<check_divert> the value to put in your
192 form can be obtained from C<secret_hidden_val>; C<secret_hidden_html>
193 will generate the whole HTML C<< <input...> >> element.
195 =head3 Mutation-ignorant applications
197 For mutation-ignorant applications (see above), all forms etc. should
198 include the hidden parameter (and as discussed, they must all use
199 POST rather than GET).
201 =head3 Mutation-aware applications
203 For mutation-aware applications, whether to include the secret
204 parameter depends on the kind of request. CGI::Auth::Flexible knows
205 when it is necessary. You should find out by calling
208 If it is inconvenient to call C<need_add_hidden> at runtime, you can
209 rely instead on the following promises: All POST requests (which
210 includes all mutating requests) need the parameter. The return value
211 of need_add_hidden depends only on the $method and $reqtype
212 parameters, so you can query it once and remember the answer.
213 HTML page load GETs do not need the parameter. It is better to
214 err on the side of including the parameter.
216 If you really must, you can call C<need_add_hidden> "on the bench"
217 during development and bake the answer into your application code
218 structure. However, if you do that and a new vulnerability was
219 discovered which is fixed by changing the answer, updating
220 CGI::Auth::Flexible wouldn't be sufficient to fix it.
222 =head3 Mutation-aware applications - non-page requests
224 If your mutation-aware application supports non-page resources (AJAX
225 and JSON requests, stylesheets, favicons, etc.) it must inform
226 CGI::Auth::Flexible when it is handling such a request, by calling
229 Normally C<check_nonpage> will simply return (and you can ignore the
230 return value). However, if there is an attack (or, perhaps, a bug) it
231 will die, stopping the attack.
233 (You do not need to call C<check_nonpage> for POST requests, but it is
238 CGI::Auth::Flexible needs to store various information in plain files;
239 it does this in the directory specified by the C<dir> parameter.
241 =head1 SOURCE CODE DOWNLOAD
243 By default, CGI::Auth::Flexible provides a facility for users to
244 download the source code for the running version of your web
247 This facility makes a number of important assumptions which you need
248 to check. Note that if the provided facility is not sufficient
249 because your application is more sophisticated than it copes with (or
250 if you disable the builtin facility), you may need to implement a
251 functioning alternative to avoid violating the AGPLv3 licence.
253 Here are the most important (default) assumptions:
259 Your app's source code is available by looking at @INC, $0 and
260 S<$ENV{'SCRIPT_FILENAME'}> (the B<source items>). See
261 C<srcdump_listitems>. Where these point to files or directories under
262 revision control, the source item is the whole containing vcs tree.
266 Specifically, there are no compiled or autogenerated Perl
267 files, Javascript resources, etc., which are not contained in one of
268 the source item directories. (Files which came with your operating
269 system install don't need to be shipped as they fall under the system
274 You have not installed any modified versions of system
275 libraries (including system-supplied Perl modules) in C</usr> outside
276 C</usr/local>. See C<srcdump_system_dir>.
280 For each source item in a dvcs, the entire dvcs history does
281 not contain anything confidential (or libellous). Also, all files which
282 contain secrets are in the dvcs's I<.ignore> file. See
283 C<srcdump_vcsscript_git> et al.
287 For each source item NOT in a dvcs, there are no confidential
288 files with the world-readable bit set (being in a world-inaccessible
289 directory is not sufficient). See C<srcdump_excludes>.
293 You have none of your app's source code in C</etc>.
297 You don't regard pathnames on your server as secret.
301 You don't intentionally load Perl code by virtue of C<.>
302 being in C<@INC> by default. (See C<srcdump_filter_cwd>.)
306 =head1 MAIN FUNCTIONS AND METHODS
310 =item C<< CGI::Auth::Flexible->new_verifier(setting => value, ...) >>
312 Initialises an instance and returns a verifier object.
313 The arguments are setting pairs like a hash initialiser.
314 See L</SETTINGS> below.
316 =item C<< $verifier->new_request($cgi_query) >>
318 Prepares to process a request. I<$cgi_query> should normally
319 be the query object from L<CGI(3perl)>. Most of the default
320 hook methods assume that it is; however if you replace enough of
321 the hook methods then you can pass any value you like and it
322 will be passed to your hooks.
324 The return value is the authentication request object (I<$authreq>)
325 which is used to check the incoming request and will contain
326 information about its credentials.
328 =item C<< $authreq->check_divert() >>
330 Checks whether the user is logged in. Returns undef if the user is
331 logged in and we should service the request. Otherwise returns a
332 divert spec (see L</DIVERT SPEC>) saying what should happen instead.
334 This method may die if it doesn't like the request, in which case
335 the request needs to be rejected.
337 =item C<< $authreq->check_ok() >>
339 Checks whether the user is logged in. Returns true if the user is
340 logged in and we should service the request.
342 Otherwise it handles the request itself, generating any appropriate
343 redirect, login form, or continuation page. It then returns false and
344 the application should not process the request further.
346 =item C<< $verifier->disconnect() >>
348 Discards the resources (open files, etc.) in the verifier object.
352 =head REQUEST-HANDLING FUNCTIONS AND METHODS
354 All of these are only valid after C<check_divert> or C<check_ok> has
355 been called. (In the case of C<check_ok> it won't normally be sensible
356 to call these functions unless C<check_ok> returned true.)
358 =item C<< $authreq->get_divert() >>
360 Returns the value previously returned by C<check_divert>.
362 =item C<< $authreq->get_username() >>
364 Returns the name of the logged-in user. If the user was not logged
365 in (or their session had timed out, or something), returns undef.
367 =head RESPONSE-RELATED FUNCTIONS AND METHODS
369 =item C<< $authreq->url_with_query_params($params, [$nonpagetype]) >>
371 Convenience function which returns a url for a GET request to this
374 I<$params> is a hashref specifying the parameters and the PATH_INFO.
375 The keys are the parameter names, and the values are array refs with
376 the parameter value(s) (as strings, as yet unquoted). (They are array
377 refs because it is possible to pass multiple values for the same
378 parameter in a single request; normally each arrayref would be a
381 The request path will be the path to the application. If a parameter
382 with name C<< '' >> is supplied, it is taken as the PATH_INFO - its
383 value will be appended to the application path. (It should normally
384 start with C<< / >>, and only one value should be supplied.)
386 =item C<< $authreq->chain_params() >>
388 Returns a hash of the "relevant" parameters to this request, in a form
389 used by XXX. This is all of the query parameters which are not
390 related to CGI::Auth::Flexible. The PATH_INFO from the request is
391 returned as the parameter C<< '' >>.