package Catalyst::Plugin::Authentication::Credential::OpenID; use strict; use warnings; our $VERSION = '0.03'; use Net::OpenID::Consumer; use LWPx::ParanoidAgent; use UNIVERSAL::require; sub setup { my $c = shift; my $config = $c->config->{authentication}->{openid} ||= {}; ( $config->{user_class} ||= "Catalyst::Plugin::Authentication::User::Hash" )->require; $c->NEXT::setup(@_); } sub authenticate_openid { my($c, $uri) = @_; my $config = $c->config->{authentication}->{openid}; my $csr = Net::OpenID::Consumer->new( ua => LWPx::ParanoidAgent->new, args => $c->req->params, consumer_secret => sub { $_[0] }, ); my @try_params = qw( openid_url openid_identifier claimed_uri ); if ($uri ||= (grep defined, @{$c->req->params}{@try_params})[0]) { my $current = $c->req->uri; $current->query(undef); # no query my $identity = $csr->claimed_identity($uri) or Catalyst::Exception->throw($csr->err); my $check_url = $identity->check_url( return_to => $current . '?openid-check=1', trust_root => $current, delayed_return => 1, ); $c->res->redirect($check_url); return 0; } elsif ($c->req->param('openid-check')) { if (my $setup_url = $csr->user_setup_url) { $c->res->redirect($setup_url); return 0; } elsif ($csr->user_cancel) { return 0; } elsif (my $identity = $csr->verified_identity) { my $user = +{ map { $_ => scalar $identity->$_ } qw( url display rss atom foaf declared_rss declared_atom declared_foaf foafmaker ) }; my $store = $config->{store} || $c->default_auth_store; if ( $store and my $store_user = $store->get_user( $user->{url}, $user ) ) { $c->set_authenticated($store_user); } else { $user = $config->{user_class}->new($user); $c->set_authenticated($user); } return 1; } else { Catalyst::Exception->throw("Error validating identity: " . $csr->err); } } else { return 0; } } 1; __END__ =for stopwords Flickr OpenID TypeKey app auth callback foaf foafmaker plugins rss url URI =head1 NAME Catalyst::Plugin::Authentication::Credential::OpenID - OpenID credential for Catalyst::Auth framework =head1 SYNOPSIS use Catalyst qw/ Authentication Authentication::Credential::OpenID Session Session::Store::FastMmap Session::State::Cookie /; # MyApp.yaml -- optional authentication: openid: use_session: 1 user_class: MyApp::M::User::OpenID # whatever in your Controller pm sub default : Private { my($self, $c) = @_; if ($c->user_exists) { ... } } sub signin_openid : Local { my($self, $c) = @_; if ($c->authenticate_openid) { $c->res->redirect( $c->uri_for('/') ); } } # foo.tt
=head1 DESCRIPTION Catalyst::Plugin::Authentication::Credential::OpenID is an OpenID credential for Catalyst::Plugin::Authentication framework. =head1 METHODS =over 4 =item authenticate_openid $c->authenticate_openid; Call this method in the action you'd like to authenticate the user via OpenID. Returns 0 if auth is not successful, and 1 if user is authenticated. User class specified with I config, which defaults to Catalyst::Plugin::Authentication::User::Hash, will be instantiated with the following parameters. By default, L method looks for claimed URI parameter from the form field named C, C or C. If you want to use another form field name, call it like: $c->authenticate_openid( $c->req->param('myopenid_param') ); =over 8 =item url =item display =item rss =item atom =item foaf =item declared_rss =item declared_atom =item declared_foaf =item foafmaker =back See L for details. =back =head1 DIFFERENCE WITH Authentication::OpenID There's already Catalyst::Plugin::Authentication::OpenID (Auth::OpenID) and this plugin tries to deprecate it. =over 4 =item * Don't use this plugin with Auth::OpenID since method names will conflict and your app won't work. =item * Auth::OpenID uses your root path (/) as an authentication callback but this plugin uses the current path, which means you can use this plugin with other Credential plugins, like Flickr or TypeKey. =item * This plugin is NOT a drop-in replacement for Auth::OpenID, but your app needs only slight modifications to work with this one. =item * This plugin is based on Catalyst authentication framework, which means you can specify I or I in your app config and this modules does the right thing, like other Credential modules. This crates new User object if authentication is successful, and works with Session too. =back =head1 AUTHOR Six Apart, Ltd. Ecpan@sixapart.comE =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO L, L =cut