1Net::OpenID::Consumer(3U)ser Contributed Perl DocumentatiNoent::OpenID::Consumer(3)
2
3
4
6 Net::OpenID::Consumer - Library for consumers of OpenID identities
7
9 version 1.18
10
12 use Net::OpenID::Consumer;
13
14 my $csr = Net::OpenID::Consumer->new(
15 ua => LWPx::ParanoidAgent->new,
16 cache => Cache::File->new( cache_root => '/tmp/mycache' ),
17 args => $cgi,
18 consumer_secret => ...,
19 required_root => "http://site.example.com/",
20 assoc_options => [
21 max_encrypt => 1,
22 session_no_encrypt_https => 1,
23 ],
24 );
25
26 # Say a user enters "bradfitz.com" as his/her identity. The first
27 # step is to perform discovery, i.e., fetch that page, parse it,
28 # find out the actual identity provider and other useful information,
29 # which gets encapsulated in a Net::OpenID::ClaimedIdentity object:
30
31 my $claimed_identity = $csr->claimed_identity("bradfitz.com");
32 unless ($claimed_identity) {
33 die "not actually an openid? " . $csr->err;
34 }
35
36 # We can then launch the actual authentication of this identity.
37 # The first step is to redirect the user to the appropriate URL at
38 # the identity provider. This URL is constructed as follows:
39 #
40 my $check_url = $claimed_identity->check_url(
41 return_to => "http://example.com/openid-check.app?yourarg=val",
42 trust_root => "http://example.com/",
43
44 # to do a "checkid_setup mode" request, in which the user can
45 # interact with the provider, e.g., so that the user can sign in
46 # there if s/he has not done so already, you will need this,
47 delayed_return => 1
48
49 # otherwise, this will be a "check_immediate mode" request, the
50 # provider will have to immediately return some kind of answer
51 # without interaction
52 );
53
54 # Once you redirect the user to $check_url, the provider should
55 # eventually redirect back, at which point you need some kind of
56 # handler at openid-check.app to deal with that response.
57
58 # You can either use the callback-based API (recommended)...
59 #
60 $csr->handle_server_response(
61 not_openid => sub {
62 die "Not an OpenID message";
63 },
64 setup_needed => sub {
65 if ($csr->message->protocol_version >= 2) {
66 # (OpenID 2) retry request in checkid_setup mode (above)
67 }
68 else {
69 # (OpenID 1) redirect user to $csr->user_setup_url
70 }
71 },
72 cancelled => sub {
73 # User hit cancel; restore application state prior to check_url
74 },
75 verified => sub {
76 my ($vident) = @_;
77 my $verified_url = $vident->url;
78 print "You are $verified_url !";
79 },
80 error => sub {
81 my ($errcode,$errtext) = @_;
82 die("Error validating identity: $errcode: $errcode");
83 },
84 );
85
86 # ... or handle the various cases yourself
87 #
88 unless ($csr->is_server_response) {
89 die "Not an OpenID message";
90 } elsif ($csr->setup_needed) {
91 # (OpenID 2) retry request in checkid_setup mode
92 # (OpenID 1) redirect/link/popup user to $csr->user_setup_url
93 } elsif ($csr->user_cancel) {
94 # User hit cancel; restore application state prior to check_url
95 } elsif (my $vident = $csr->verified_identity) {
96 my $verified_url = $vident->url;
97 print "You are $verified_url !";
98 } else {
99 die "Error validating identity: " . $csr->err;
100 }
101
103 This is the Perl API for (the consumer half of) OpenID, a distributed
104 identity system based on proving you own a URL, which is then your
105 identity. More information is available at:
106
107 http://openid.net/
108
110 new
111 my $csr = Net::OpenID::Consumer->new( %options );
112
113 The following option names are recognized: "ua", "cache", "args",
114 "consumer_secret", "minimum_version", "required_root",
115 "assoc_options", and "nonce_options" in the constructor. In each
116 case the option value is treated exactly as the argument to the
117 corresponding method described below under Configuration.
118
120 State
121 $csr->message($key)
122 Returns the value for the given key/field from the OpenID protocol
123 message contained in the request URL parameters (i.e., the value
124 for the URL parameter "openid.$key"). This can only be used to
125 obtain core OpenID fields not extension fields.
126
127 Calling this method without a $key argument returns a
128 Net::OpenID::IndirectMessage object representing the protocol
129 message, at which point the various object methods are available,
130 including
131
132 $csr->message->protocol_version
133 $csr->message->has_ext
134 $csr->message->get_ext
135
136 Returns undef in either case if no URL parameters have been
137 supplied (i.e., because args() has not been initialized) or if the
138 request is not an actual OpenID message.
139
140 $csr->err
141 Returns the last error, in form "errcode: errtext", as set by the
142 various handlers below.
143
144 $csr->errcode
145 Returns the last error code. See Error Codes below.
146
147 $csr->errtext
148 Returns the last error text.
149
150 $csr->json_err
151 Returns the last error code/text in JSON format.
152
153 Configuration
154 $csr->ua($user_agent)
155 $csr->ua
156 Getter/setter for the LWP::UserAgent (or subclass) instance which
157 will be used when direct HTTP requests to a provider are needed.
158 It's highly recommended that you use LWPx::ParanoidAgent, or at
159 least read its documentation so you're aware of why you should
160 care.
161
162 $csr->cache($cache)
163 $csr->cache
164 Getter/setter for the cache instance which is used for storing
165 fetched HTML or XRDS pages, keys for associations with identity
166 providers, and received response_nonce values from positive
167 provider assertions.
168
169 The $cache object can be anything that has a ->get($key) and
170 ->set($key,$value[,$expire]) methods. See URI::Fetch for more
171 information. This cache object is passed to URI::Fetch directly.
172
173 Setting a cache instance is not absolutely required, But without
174 it, provider associations will not be possible and the same pages
175 may be fetched multiple times during discovery. It will also not
176 be possible to check for repetition of the response_nonce, which
177 may then leave you open to replay attacks.
178
179 $csr->consumer_secret($scalar)
180 $csr->consumer_secret($code)
181 $code = $csr->B<consumer_secret>; ($secret) = $code->($time);
182
183 The consumer secret is used to generate self-signed nonces for the
184 return_to URL, to prevent spoofing.
185
186 In the simplest (and least secure) form, you configure a static
187 secret value with a scalar. If you use this method and change the
188 scalar value, any outstanding requests from the last 30 seconds or
189 so will fail.
190
191 You may also supply a subref that takes one argument, $time, a unix
192 timestamp and returns a secret.
193
194 Your secret may not exceed 255 characters.
195
196 For the best protection against replays and login cross-site
197 request forgery, consumer_secret should additionally depend on
198 something known to be specific to the client browser instance and
199 not visible to an attacker. If "SSH_SESSION_ID" is available, you
200 should use that. Otherwise you'll need to set a (Secure) cookie on
201 the (HTTPS) page where the signin form appears in order to
202 establish a pre-login session, then make sure to change this cookie
203 upon successful login.
204
205 $csr->minimum_version(2)
206 $csr->minimum_version
207 Get or set the minimum OpenID protocol version supported. Currently
208 the only useful value you can set here is 2, which will cause 1.1
209 identifiers to fail discovery with the error
210 "protocol_version_incorrect" and responses from version 1 providers
211 to not be recognized.
212
213 In most cases you'll want to allow both 1.1 and 2.0 identifiers,
214 which is the default. If you want, you can set this property to 1
215 to make this behavior explicit.
216
217 $csr->args($ref)
218 $csr->args($param)
219 $csr->args
220 Can be used in 1 of 3 ways:
221
222 1. Set the object from which URL parameter names and values are to
223 be retrieved:
224
225 $csr->args( $reference )
226
227 where $reference is either an unblessed "HASH" ref, a "CODE"
228 ref, or some kind of "request object" — the latter being either
229 a CGI, Apache, Apache::Request, Apache2::Request, or
230 Plack::Request object.
231
232 If you pass in a "CODE" ref, it must,
233
234 • given a single parameter name argument, return the
235 corresponding parameter value, and,
236
237 • given no arguments at all, return the full list of
238 parameter names from the request.
239
240 If you pass in an Apache (mod_perl 1.x interface) object and
241 this is a POST request, you must not have already called
242 "$r->content" as this routine will be making said call itself
243 in order to extract the request parameters.
244
245 2. Get a parameter value:
246
247 my $foo = $csr->args("foo");
248
249 When given an unblessed scalar, it retrieves the value. It
250 croaks if you haven't defined a way to get at the parameters.
251
252 Most callers should instead use the "message" method above,
253 which abstracts away the need to understand OpenID's message
254 serialization.
255
256 3. Get the parameter getter:
257
258 my $code = $csr->args;
259
260 this being a subref that takes a parameter name and returns the
261 corresponding value.
262
263 Most callers should instead use the "message" method above with
264 no arguments, which returns an object from which extension
265 attributes can be obtained by their documented namespace URI.
266
267 $csr->required_root($url_prefix)
268 $csr->required_root
269 Gets or sets the string prefix that, if nonempty, all return_to
270 URLs must start with. Messages with return_to URLS that don't
271 match will be considered invalid (spoofed from another site).
272
273 $csr->assoc_options(...)
274 $csr->assoc_options
275 Get or sets the hash of parameters that determine how associations
276 with identity providers will be made. Available options include:
277
278 "assoc_type"
279 Association type, (default 'HMAC-SHA1')
280
281 "session_type"
282 Association session type, (default 'DH-SHA1')
283
284 "max_encrypt"
285 (boolean) Use best encryption available for protocol version
286 for both session type and association type. This overrides
287 "session_type" and "assoc_type"
288
289 "session_no_encrypt_https"
290 (boolean) Use an unencrypted session type if the ID provider
291 URL scheme is "https:". This overrides "max_encrypt" if both
292 are set.
293
294 "allow_eavesdropping"
295 (boolean) Because it is generally a bad idea, we abort
296 associations where an unencrypted session over a non-SSL
297 connection is called for. However the OpenID 1.1 specification
298 technically allows this, so if that is what you really want,
299 set this flag true. Ignored under protocol version 2.
300
301 $csr->nonce_options(...)
302 $csr->nonce_options
303 Gets or sets the hash of options for how response_nonce should be
304 checked.
305
306 In OpenID 2.0, response_nonce is sent by the identity provider as
307 part of a positive identity assertion in order to help prevent
308 replay attacks. In the check_authentication phase, the provider is
309 also required to not authenticate the same response_nonce twice.
310
311 The relying party is strongly encouraged but not required to reject
312 multiple occurrences of a nonce (which can matter if associations
313 are in use and there is no check_authentication phase). Relying
314 party may also choose to reject a nonce on the basis of the
315 timestamp being out of an acceptable range.
316
317 Available options include:
318
319 "nocheck"
320 (boolean) Skip response_nonce checking entirely. This
321 overrides all other nonce_options.
322
323 "nocheck" is implied and is the only possibility if $csr->cache
324 is unset.
325
326 "lifetime"
327 (integer) Cache entries for nonces will expire after this many
328 seconds.
329
330 Defaults to the value of "window", below.
331
332 If "lifetime" is zero or negative, expiration times will not be
333 set at all; entries will expire as per the default behavior for
334 your cache (or you will need to purge them via some separate
335 process).
336
337 If your cache implementation ignores the third argument on
338 $entry->set() calls (see Cache::Entry), then this option has no
339 effect beyond serving as a default for "window".
340
341 "ignoretime"
342 (boolean) Do not do any checking of timestamps, i.e., only test
343 whether nonce is in the cache. This overrides all other nonce
344 options except for "lifetime" and "nocheck"
345
346 "skew"
347 (integer) Number of seconds that a provider clock can be ahead
348 of ours before we deem it to be misconfigured.
349
350 Default skew is 300 (5 minutes) or "window/2", if "window" is
351 specified and "window/2" is smaller.
352
353 ("skew" is treated as 0 if set negative, but don't do that).
354
355 Misconfiguration of the provider clock means its timestamps are
356 not reliable, which then means there is no way to know whether
357 or not the nonce could have been sent before the start of the
358 cache window, which nullifies any obligation to detect all
359 multiply sent nonces. Conversely, if proper configuration can
360 be assumed, then the timestamp value minus "skew" will be the
361 earliest possible time that we could have received a previous
362 instance of this response_nonce, and if the cache is reliable
363 about holding entries from that time forward, then (and only
364 then) can one be certain that an uncached nonce instance is
365 indeed the first.
366
367 "start"
368 (integer) Reject nonces where timestamp minus "skew" is earlier
369 than "start" (absolute seconds; default is zero a.k.a. midnight
370 1/1/1970 UTC)
371
372 If you know the start time of your HTTP server (or your cache
373 server, if that is separate — or the maximum of the start times
374 if you have multiple cache servers), you should use this option
375 to declare that.
376
377 "window"
378 (integer) Reject nonces where timestamp minus "skew" is more
379 than "window" seconds ago. Zero or negative values of "window"
380 are treated as infinite (i.e., allow everything).
381
382 If "lifetime" is specified, "window" defaults to that. If
383 "lifetime" is not specified, "window" defaults to 1800 (30
384 minutes), adjusted upwards if "skew" is specified and larger
385 than the default skew.
386
387 On general principles, "window" should be a maximal expected
388 propagation delay plus twice the "skew".
389
390 Values between 0 and "skew" (causing all nonces to be rejected)
391 and values greater than "lifetime" (cache may fail to keep all
392 nonces that are still within the window) are not recommended.
393
394 "timecop"
395 (boolean) Reject nonces from The Future (i.e., timestamped more
396 than "skew" seconds from now).
397
398 Note that rejecting future nonces is not required. Nor does it
399 protect from anything since an attacker can retry the message
400 once it has expired from the cache but is still within the time
401 interval where we would not yet expect that it could expire —
402 this being the essential problem with future nonces. It may,
403 however, be useful to have warnings about misconfigured
404 provider clocks — and hence about this insecurity — at the cost
405 of impairing interoperability (since this rejects messages that
406 are otherwise allowed by the protocol), hence this option.
407
408 In most cases it will be enough to either set "nocheck" to dispense
409 with response_nonce checking entirely because some other (better)
410 method of preventing replay attacks (see consumer_secret) has been
411 implemented, or use "lifetime" to declare/set the lifetime of cache
412 entries for nonces whether because the default lifetime is
413 unsatisfactory or because the cache implementation is incapable of
414 setting individual expiration times. All other options should
415 default reasonably in these cases.
416
417 In order for the nonce check to be as reliable/secure as possible
418 (i.e., that it block all instances of duplicate nonces from
419 properly configured providers as defined by "skew", which is the
420 best we can do), "start" must be no earlier than the cache start
421 time and the cache must be guaranteed to hold nonce entries for at
422 least "window" seconds (though, to be sure, if you can tolerate
423 being vulnerable for the first "window" seconds of a server run,
424 then you do not need to set "start").
425
426 Performing Discovery
427 $csr->claimed_identity($url)
428 Given a user-entered $url (which could be missing http://, or have
429 extra whitespace, etc), converts it to canonical form, performs
430 partial discovery to confirm that at least one provider endpoint
431 exists, and returns a Net::OpenID::ClaimedIdentity object, or, on
432 failure of any of the above, returns undef and sets last error
433 ($csr->err).
434
435 Note that the identity returned is not verified yet. It's only who
436 the user claims they are, but they could be lying.
437
438 If this method returns undef, an error code will be set. See Error
439 Codes below.
440
441 Handling Provider Responses
442 The following routines are for handling a redirected provider response
443 and assume that, among other things, $csr->args has been properly
444 populated with the URL parameters.
445
446 $csr->handle_server_response( %callbacks );
447 When a request comes in that contains a response from an OpenID
448 provider, figure out what it means and dispatch to an appropriate
449 callback to handle the request. This is the callback-based
450 alternative to explicitly calling the methods below in the correct
451 sequence, and is recommended unless you need to do something
452 strange.
453
454 Anything you return from the selected callback function will be
455 returned by this method verbatim. This is useful if the caller
456 needs to return something different in each case.
457
458 The available callbacks are:
459
460 "not_openid"
461 the request isn't an OpenID response after all.
462
463 "setup_needed"
464 a checkid_immediate mode request was rejected, indicating that
465 the provider requires user interaction.
466
467 "cancelled"
468 the user cancelled the authentication request from the
469 provider's UI.
470
471 "verified ($verified_identity)"
472 the user's identity has been successfully verified. A
473 Net::OpenID::VerifiedIdentity object is passed in.
474
475 "error ($errcode, $errmsg)"
476 an error has occurred. An error code and message are provided.
477 See Error Codes below for the meanings of the codes.
478
479 For the sake of legacy code we also allow
480
481 "setup_required ($setup_url)"
482 [DEPRECATED] a checkid_immediate mode request was rejected and
483 $setup_url was provided.
484
485 Clients using this callback should be updated to use
486 setup_needed at the earliest opportunity. Here $setup_url is
487 the same as returned by $csr->user_setup_url.
488
489 $csr->is_server_response
490 Returns true if a set of URL parameters has been supplied (via
491 $csr->args) and constitutes an actual OpenID protocol message.
492
493 $csr->setup_needed
494 Returns true if a checkid_immediate request failed because the
495 provider requires user interaction. The correct action to take at
496 this point depends on the OpenID protocol version
497
498 (Version 1) Redirect to or otherwise make available a link to
499 $csr->"user_setup_url".
500
501 (Version 2) Retry the request in checkid_setup mode; the provider
502 will then issue redirects as needed.
503
504 N.B.: While some providers have been known to supply the
505 "user_setup_url" parameter in Version 2 "setup_needed"
506 responses, you cannot rely on this, and, moreover, since the
507 OpenID 2.0 specification has nothing to say about the meaning
508 of such a parameter, you cannot rely on it meaning anything in
509 particular even if it is supplied.
510
511 $csr->user_setup_url( [ %opts ] )
512 (Version 1 only) Returns the URL the user must return to in order
513 to login, setup trust, or do whatever the identity provider needs
514 them to do in order to make the identity assertion which they
515 previously initiated by entering their claimed identity URL.
516
517 N.B.: Checking whether "user_setup_url" is set in order to
518 determine whether a checkid_immediate request failed is
519 DEPRECATED and will fail under OpenID 2.0. Use setup_needed()
520 instead.
521
522 The base URL that this function returns can be modified by using
523 the following options in %opts:
524
525 "post_grant"
526 What you're asking the identity provider to do with the user
527 after they setup trust. Can be either "return" or "close" to
528 return the user back to the return_to URL, or close the browser
529 window with JavaScript. If you don't specify, the behavior is
530 undefined (probably the user gets a dead-end page with a link
531 back to the return_to URL). In any case, the identity provider
532 can do whatever it wants, so don't depend on this.
533
534 $csr->user_cancel
535 Returns true if the user declined to share their identity, false
536 otherwise. (This function is literally one line: returns true if
537 "openid.mode" eq "cancel")
538
539 It's then your job to restore your app to where it was prior to
540 redirecting them off to the user_setup_url, using the other query
541 parameters that you'd sent along in your return_to URL.
542
543 $csr->verified_identity( [ %opts ] )
544 Returns a Net::OpenID::VerifiedIdentity object, or returns undef
545 and sets last error ($csr->err). Verification includes double-
546 checking the reported identity URL declares the identity provider,
547 verifying the signature, etc.
548
549 The options in %opts may contain:
550
551 "required_root"
552 Sets the required_root just for this request. Values returns
553 to its previous value afterwards.
554
555 If this method returns undef, an error code will be set. See Error
556 Codes below.
557
559 This is the complete list of error codes that can be set. Errors
560 marked with (C) are set by claimed_identity. Other errors occur during
561 handling of provider responses and can be set by args (A),
562 verified_identity (V), and user_setup_url (S), all of which can show up
563 in the "error" callback for handle_server_response.
564
565 "provider_error"
566 (A) The protocol message is a (2.0) error mode (i.e.,
567 "openid.mode = 'error'") message, typically used for provider-
568 specific error responses. Use $csr->message to get at the
569 "contact" and "reference" fields.
570
571 "empty_url"
572 (C) Tried to do discovery on an empty or all-whitespace string.
573
574 "bogus_url"
575 (C) Tried to do discovery on a non-http:/https: URL.
576
577 "protocol_version_incorrect"
578 (C) None of the ID providers found support even the minimum
579 protocol version ($csr->minimum_version)
580
581 "no_identity_server"
582 (CV) Tried to do discovery on a URL that does not seem to have
583 any providers at all.
584
585 "bad_mode"
586 (SV) The "openid.mode" was expected to be "id_res" (positive
587 assertion or, in version 1, checkid_immediate failed).
588
589 "no_identity"
590 (V) The "openid.identity" parameter is missing.
591
592 "no_sig"
593 (V) The "openid.sig" parameter is missing.
594
595 "no_return_to"
596 (V) The "openid.return_to" parameter is missing
597
598 "bogus_return_to"
599 (V) The "return_to" URL does not match $csr->required_root
600
601 "nonce_missing"
602 (V) The "openid.response_nonce" parameter is missing.
603
604 "nonce_reused"
605 (V) A previous assertion from this provider used this
606 response_nonce already. Someone may be attempting a replay
607 attack.
608
609 "nonce_format"
610 (V) Either the response_nonce timestamp was not in the correct
611 format (e.g., tried to have fractional seconds or not UTC) or
612 one of the components was out of range (e.g., month = 13).
613
614 "nonce_future"
615 (V) "timecop" was set and we got a response_nonce that was more
616 than "skew" seconds into the future.
617
618 "nonce_stale"
619 (V) We got a response_nonce that was either prior to the start
620 time or more than window seconds ago.
621
622 "time_expired"
623 (V) The return_to signature time ("oic.time") is from too long
624 ago.
625
626 "time_in_future"
627 (V) The return_to signature time ("oic.time") is too far into
628 the future.
629
630 "time_bad_sig"
631 (V) The HMAC of the return_to signature ("oic.time") is not
632 what it should be.
633
634 "server_not_allowed"
635 (V) None of the provider endpoints found for the given ID match
636 the server specified by the "openid.op_endpoint" parameter
637 (OpenID 2 only).
638
639 "unexpected_url_redirect"
640 (V) Discovery for the given ID ended up at the wrong place
641
642 "bogus_delegation"
643 (V) Asserted identity ("openid.identity") does not match
644 claimed_id or local_id/delegate.
645
646 "unsigned_field"
647 (V) In OpenID 2.0, "openid.op_endpoint", "openid.return_to",
648 "openid.response_nonce", and "openid.assoc_handle" must always
649 be signed, while "openid.claimed_id" and "openid.identity" must
650 be signed if present.
651
652 "expired_association"
653 (V) "openid.assoc_handle" is for an association that has
654 expired.
655
656 "signature_mismatch"
657 (V) An attempt to confirm the positive assertion using the
658 association given by "openid.assoc_handle" failed; the
659 signature is not what it should be.
660
661 "naive_verify_failed_network"
662 (V) An attempt to confirm the positive assertion via direct
663 contact (check_authentication) with the provider failed with no
664 response or a bad status code (!= 200).
665
666 "naive_verify_failed_return"
667 (V) An attempt to confirm a positive assertion via direct
668 contact (check_authentication) received an explicitly negative
669 response ("openid.is_valid = FALSE").
670
672 XRI-based identities are not supported.
673
674 Meanwhile, here are answers to the security profile questions from
675 section 15.6 of the OpenID 2.0 specification
676 <http://openid.net/specs/openid-authentication-2_0.html#anchor47> that
677 are relevant to the Consumer/Relying-Party:
678
679 1. Are wildcards allowed in realms? Yes.
680
681 2. N/A.
682
683 3. Types of claimed identifiers accepted. HTTP or HTTPS
684
685 4. Are self-issued certificates allowed for authentication? Depends
686 entirely on the user agent ("ua") supplied. LWP::UserAgent, as of
687 version 6.0, can be configured to only accept connections to sites
688 with certificates deriving from a set of trusted roots.
689
690 5. Must the XRDS file be signed? No.
691
692 6. Must the XRDS file be retrieved over secure channel? No.
693
694 7. What types of session types can be used when creating associations?
695 Any of "no-encryption","DH-SHA1","DH-SHA256"
696
697 8. N/A.
698
699 9. N/A.
700
701 10. Must the association request take place over a secure channel? If
702 the session type is "no-encryption", then Yes for version 2.0
703 providers and likewise for version 1.1 providers if
704 "allow_eavesdropping" is not set, otherwise No.
705
707 This module is Copyright (c) 2005 Brad Fitzpatrick. All rights
708 reserved.
709
710 You may distribute under the terms of either the GNU General Public
711 License or the Artistic License, as specified in the Perl README file.
712 If you need more liberal licensing terms, please contact the
713 maintainer.
714
716 This is free software. IT COMES WITHOUT WARRANTY OF ANY KIND.
717
719 The Net::OpenID family of modules has a mailing list powered by Google
720 Groups. For more information, see
721 <http://groups.google.com/group/openid-perl>.
722
724 OpenID website: <http://openid.net/>
725
726 Net::OpenID::ClaimedIdentity -- part of this module
727
728 Net::OpenID::VerifiedIdentity -- part of this module
729
730 Net::OpenID::Server -- another module, for implementing an OpenID
731 identity provider/server
732
734 Brad Fitzpatrick <brad@danga.com>
735
736 Tatsuhiko Miyagawa <miyagawa@sixapart.com>
737
738 Martin Atkins <mart@degeneration.co.uk>
739
740 Robert Norris <rob@eatenbyagrue.org>
741
742 Roger Crew <crew@cs.stanford.edu>
743
744
745
746perl v5.36.0 2023-01-20 Net::OpenID::Consumer(3)