1NAME
2    Catalyst::Authentication::Credential::OpenID - OpenID credential for
3    Catalyst::Plugin::Authentication framework.
4
5BACKWARDS COMPATIBILITY CHANGES
6  EXTENSION_ARGS v EXTENSIONS
7    NB: The extensions were previously configured under the key
8    "extension_args". They are now configured under "extensions".
9    "extension_args" is no longer honored.
10
11    As previously noted, "EXTENSIONS TO OPENID", I have not tested the
12    extensions. I would be grateful for any feedback or, better, tests.
13
14  FATALS
15    The problems encountered by failed OpenID operations have always been
16    fatals in the past. This is unexpected behavior for most users as it
17    differs from other credentials. Authentication errors here are no longer
18    fatal. Debug/error output is improved to offset the loss of information.
19    If for some reason you would prefer the legacy/fatal behavior, set the
20    configuration variable "errors_are_fatal" to a true value.
21
22SYNOPSIS
23    In MyApp.pm-
24
25     use Catalyst qw/
26        Authentication
27        Session
28        Session::Store::FastMmap
29        Session::State::Cookie
30     /;
31
32    Somewhere in myapp.conf-
33
34     <Plugin::Authentication>
35         default_realm   openid
36         <realms>
37             <openid>
38                 <credential>
39                     class   OpenID
40                     ua_class   LWP::UserAgent
41                 </credential>
42             </openid>
43         </realms>
44     </Plugin::Authentication>
45
46    Or in your myapp.yml if you're using YAML instead-
47
48     Plugin::Authentication:
49       default_realm: openid
50       realms:
51         openid:
52           credential:
53             class: OpenID
54             ua_class: LWP::UserAgent
55
56    In a controller, perhaps "Root::openid"-
57
58     sub openid : Local {
59          my($self, $c) = @_;
60
61          if ( $c->authenticate() )
62          {
63              $c->flash(message => "You signed in with OpenID!");
64              $c->res->redirect( $c->uri_for('/') );
65          }
66          else
67          {
68              # Present OpenID form.
69          }
70     }
71
72    And a Template to match in "openid.tt"-
73
74     <form action="[% c.uri_for('/openid') %]" method="GET" name="openid">
75     <input type="text" name="openid_identifier" class="openid" />
76     <input type="submit" value="Sign in with OpenID" />
77     </form>
78
79DESCRIPTION
80    This is the third OpenID related authentication piece for Catalyst. The
81    first — Catalyst::Plugin::Authentication::OpenID by Benjamin Trott — was
82    deprecated by the second —
83    Catalyst::Plugin::Authentication::Credential::OpenID by Tatsuhiko
84    Miyagawa — and this is an attempt to deprecate both by conforming to the
85    newish, at the time of this module's inception, realm-based
86    authentication in Catalyst::Plugin::Authentication.
87
88     1. Catalyst::Plugin::Authentication::OpenID
89     2. Catalyst::Plugin::Authentication::Credential::OpenID
90     3. Catalyst::Authentication::Credential::OpenID
91
92    The benefit of this version is that you can use an arbitrary number of
93    authentication systems in your Catalyst application and configure and
94    call all of them in the same way.
95
96    Note that both earlier versions of OpenID authentication use the method
97    "authenticate_openid()". This module uses "authenticate()" and relies on
98    you to specify the realm. You can specify the realm as the default in
99    the configuration or inline with each "authenticate()" call; more below.
100
101    This module functions quite differently internally from the others. See
102    Catalyst::Plugin::Authentication::Internals for more about this
103    implementation.
104
105METHODS
106    $c->authenticate({},"your_openid_realm");
107        Call to authenticate the user via OpenID. Returns false if
108        authorization is unsuccessful. Sets the user into the session and
109        returns the user object if authentication succeeds.
110
111        You can see in the call above that the authentication hash is empty.
112        The implicit OpenID parameter is, as the 2.0 specification says it
113        SHOULD be, openid_identifier. You can set it anything you like in
114        your realm configuration, though, under the key "openid_field". If
115        you call "authenticate()" with the empty info hash and no configured
116        "openid_field" then only "openid_identifier" is checked.
117
118        It implicitly does this (sort of, it checks the request method too)-
119
120         my $claimed_uri = $c->req->params->{openid_identifier};
121         $c->authenticate({openid_identifier => $claimed_uri});
122
123    Catalyst::Authentication::Credential::OpenID->new()
124        You will never call this. Catalyst does it for you. The only
125        important thing you might like to know about it is that it merges
126        its realm configuration with its configuration proper. If this
127        doesn't mean anything to you, don't worry.
128
129  USER METHODS
130    Currently the only supported user class is
131    Catalyst::Plugin::Authentication::User::Hash.
132
133    $c->user->url
134    $c->user->display
135    $c->user->rss
136    $c->user->atom
137    $c->user->foaf
138    $c->user->declared_rss
139    $c->user->declared_atom
140    $c->user->declared_foaf
141    $c->user->foafmaker
142
143    See Net::OpenID::VerifiedIdentity for details.
144
145CONFIGURATION
146    Catalyst authentication is now configured entirely from your
147    application's configuration. Do not, for example, put
148    "Credential::OpenID" into your "use Catalyst ..." statement. Instead,
149    tell your application that in one of your authentication realms you will
150    use the credential.
151
152    In your application the following will give you two different
153    authentication realms. One called "members" which authenticates with
154    clear text passwords and one called "openid" which uses... uh, OpenID.
155
156     __PACKAGE__->config
157        ( name => "MyApp",
158          "Plugin::Authentication" => {
159              default_realm => "members",
160              realms => {
161                  members => {
162                      credential => {
163                          class => "Password",
164                          password_field => "password",
165                          password_type => "clear"
166                          },
167                              store => {
168                                  class => "Minimal",
169                                  users => {
170                                      paco => {
171                                          password => "l4s4v3n7ur45",
172                                      },
173                                  }
174                              }
175                  },
176                  openid => {
177                      credential => {
178                          class => "OpenID",
179                          store => {
180                              class => "OpenID",
181                          },
182                          consumer_secret => "Don't bother setting",
183                          ua_class => "LWP::UserAgent",
184                          # whitelist is only relevant for LWPx::ParanoidAgent
185                          ua_args => {
186                              whitelisted_hosts => [qw/ 127.0.0.1 localhost /],
187                          },
188                          extensions => [
189                              'http://openid.net/extensions/sreg/1.1',
190                              {
191                               required => 'email',
192                               optional => 'fullname,nickname,timezone',
193                              },
194                          ],
195                      },
196                  },
197              },
198          }
199        );
200
201    This is the same configuration in the default Catalyst configuration
202    format from Config::General.
203
204     name   MyApp
205     <Plugin::Authentication>
206         default_realm   members
207         <realms>
208             <members>
209                 <store>
210                     class   Minimal
211                     <users>
212                         <paco>
213                             password   l4s4v3n7ur45
214                         </paco>
215                     </users>
216                 </store>
217                 <credential>
218                     password_field   password
219                     password_type   clear
220                     class   Password
221                 </credential>
222             </members>
223             <openid>
224                 <credential>
225                     <store>
226                         class   OpenID
227                     </store>
228                     class   OpenID
229                     <ua_args>
230                         whitelisted_hosts   127.0.0.1
231                         whitelisted_hosts   localhost
232                     </ua_args>
233                     consumer_secret   Don't bother setting
234                     ua_class   LWP::UserAgent
235                     <extensions>
236                         http://openid.net/extensions/sreg/1.1
237                         required   email
238                         optional   fullname,nickname,timezone
239                     </extensions>
240                 </credential>
241             </openid>
242         </realms>
243     </Plugin::Authentication>
244
245    And now, the same configuration in YAML. NB: YAML is whitespace
246    sensitive.
247
248     name: MyApp
249     Plugin::Authentication:
250       default_realm: members
251       realms:
252         members:
253           credential:
254             class: Password
255             password_field: password
256             password_type: clear
257           store:
258             class: Minimal
259             users:
260               paco:
261                 password: l4s4v3n7ur45
262         openid:
263           credential:
264             class: OpenID
265             store:
266               class: OpenID
267             consumer_secret: Don't bother setting
268             ua_class: LWP::UserAgent
269             ua_args:
270               # whitelist is only relevant for LWPx::ParanoidAgent
271               whitelisted_hosts:
272                 - 127.0.0.1
273                 - localhost
274             extensions:
275                 - http://openid.net/extensions/sreg/1.1
276                 - required: email
277                   optional: fullname,nickname,timezone
278
279    NB: There is no OpenID store yet.
280
281    You can set "trust_root" now too. This is experimental and I have no
282    idea if it's right or could be better. Right now it must be a URI. It
283    was submitted as a path but this seems to limit it to the Catalyst app
284    and while easier to dynamically generate no matter where the app starts,
285    it seems like the wrong way to go. Let me know if that's mistaken.
286
287  EXTENSIONS TO OPENID
288    The Simple Registration--<http://openid.net/extensions/sreg/1.1>--(SREG)
289    extension to OpenID is supported in the Net::OpenID family now.
290    Experimental support for it is included here as of v0.12. SREG is the
291    only supported extension in OpenID 1.1. It's experimental in the sense
292    it's a new interface and barely tested. Support for OpenID extensions is
293    here to stay.
294
295    Google's OpenID is also now supported. Uh, I think.
296
297    Here is a snippet from Thorben Jändling combining Sreg and Google's
298    extenstions–
299
300     'Plugin::Authentication' => {
301        openid => {
302            credential => {
303                class => 'OpenID',
304                ua_class => 'LWP::UserAgent',
305                extensions => {
306                    'http://openid.net/extensions/sreg/1.1' => {
307                        required => 'nickname,email,fullname',
308                        optional => 'timezone,language,dob,country,gender'
309                    },
310                    'http://openid.net/srv/ax/1.0' => {
311                        mode => 'fetch_request',
312                        'type.nickname' => 'http://axschema.org/namePerson/friendly',
313                        'type.email' => 'http://axschema.org/contact/email',
314                        'type.fullname' => 'http://axschema.org/namePerson',
315                        'type.firstname' => 'http://axschema.org/namePerson/first',
316                        'type.lastname' => 'http://axschema.org/namePerson/last',
317                        'type.dob' => 'http://axschema.org/birthDate',
318                        'type.gender' => 'http://axschema.org/person/gender',
319                        'type.country' => 'http://axschema.org/contact/country/home',
320                        'type.language' => 'http://axschema.org/pref/language',
321                        'type.timezone' => 'http://axschema.org/pref/timezone',
322                        required => 'nickname,fullname,email,firstname,lastname',
323                        if_available => 'dob,gender,country,language,timezone',
324                },
325                },
326            },
327        },
328        default_realm => 'openid',
329     };
330
331  MORE ON CONFIGURATION
332    ua_args and ua_class
333        LWPx::ParanoidAgent is the default agent — "ua_class" — if it's
334        available, LWP::UserAgent if not. You don't have to set it. I
335        recommend that you do not override it. You can with any well behaved
336        LWP::UserAgent. You probably should not. LWPx::ParanoidAgent buys
337        you many defenses and extra security checks. When you allow your
338        application users freedom to initiate external requests, you open an
339        avenue for DoS (denial of service) attacks. LWPx::ParanoidAgent
340        defends against this. LWP::UserAgent and any regular subclass of it
341        will not.
342
343    consumer_secret
344        The underlying Net::OpenID::Consumer object is seeded with a secret.
345        If it's important to you to set your own, you can. The default uses
346        this package name + its version + the sorted configuration keys of
347        your Catalyst application (chopped at 255 characters if it's
348        longer). This should generally be superior to any fixed string.
349
350TODO
351    Option to suppress fatals.
352
353    Support more of the new methods in the Net::OpenID kit.
354
355    There are some interesting implications with this sort of setup. Does a
356    user aggregate realms or can a user be signed in under more than one
357    realm? The documents could contain a recipe of the self-answering OpenID
358    end-point that is in the tests.
359
360    Debug statements need to be both expanded and limited via realm
361    configuration.
362
363    Better diagnostics in errors. Debug info at all consumer calls.
364
365    Roles from provider domains? Mapped? Direct? A generic "openid"
366    auto_role?
367
368THANKS
369    To Benjamin Trott (Catalyst::Plugin::Authentication::OpenID), Tatsuhiko
370    Miyagawa (Catalyst::Plugin::Authentication::Credential::OpenID), Brad
371    Fitzpatrick for the great OpenID stuff, Martin Atkins for picking up the
372    code to handle OpenID 2.0, and Jay Kuri and everyone else who has made
373    Catalyst such a wonderful framework.
374
375    Menno Blom provided a bug fix and the hook to use OpenID extensions.
376
377LICENSE AND COPYRIGHT
378    Copyright (c) 2008-2009, Ashley Pond V "<ashley@cpan.org>". Some of
379    Tatsuhiko Miyagawa's work is reused here.
380
381    This module is free software; you can redistribute it and modify it
382    under the same terms as Perl itself. See perlartistic.
383
384DISCLAIMER OF WARRANTY
385    Because this software is licensed free of charge, there is no warranty
386    for the software, to the extent permitted by applicable law. Except when
387    otherwise stated in writing the copyright holders and other parties
388    provide the software "as is" without warranty of any kind, either
389    expressed or implied, including, but not limited to, the implied
390    warranties of merchantability and fitness for a particular purpose. The
391    entire risk as to the quality and performance of the software is with
392    you. Should the software prove defective, you assume the cost of all
393    necessary servicing, repair, or correction.
394
395    In no event unless required by applicable law or agreed to in writing
396    will any copyright holder, or any other party who may modify or
397    redistribute the software as permitted by the above license, be liable
398    to you for damages, including any general, special, incidental, or
399    consequential damages arising out of the use or inability to use the
400    software (including but not limited to loss of data or data being
401    rendered inaccurate or losses sustained by you or third parties or a
402    failure of the software to operate with any other software), even if
403    such holder or other party has been advised of the possibility of such
404    damages.
405
406SEE ALSO
407    OpenID
408        Net::OpenID::Server, Net::OpenID::VerifiedIdentity,
409        Net::OpenID::Consumer, <http://openid.net/>,
410        <http://openid.net/developers/specs/>, and
411        <http://openid.net/extensions/sreg/1.1>.
412
413    Catalyst Authentication
414        Catalyst, Catalyst::Plugin::Authentication,
415        Catalyst::Manual::Tutorial::Authorization, and
416        Catalyst::Manual::Tutorial::Authentication.
417
418    Catalyst Configuration
419        Catalyst::Plugin::ConfigLoader, Config::General, and YAML.
420
421    Miscellaneous
422        Catalyst::Manual::Tutorial, Template, LWPx::ParanoidAgent.
423
424