##@file # OpenID authentication backend file ##@class # OpenID authentication backend class. # The form must return a openIdUrl field package Lemonldap::NG::Portal::AuthOpenID; use strict; use Lemonldap::NG::Portal::Simple; use LWP::UserAgent; require Cache::FileCache; our $VERSION = '0.1'; ## @apmethod int authInit() # @return Lemonldap::NG::Portal constant sub authInit { my $self = shift; eval { require Net::OpenID::Consumer }; $self->abort( 'Unable to load Net::OpenID::Consumer', $@ ) if ($@); $self->{openIdSecret} ||= $self->{cipher}->encrypt(0); PE_OK; } ## @apmethod int extractFormInfo() # Read username return by OpenID authentication system. # @return Lemonldap::NG::Portal constant sub extractFormInfo { my $self = shift; my $ua = LWP::UserAgent->new(); # TODO : LWP options to use a proxy for example $self->{csr} = Net::OpenID::Consumer->new( ua => $ua, cache => $self->{refLocalStorage} || Cache::FileCache->new, args => $self, consumer_secret => $self->{openIdSecret}, required_root => $self->{portal}, ); my ( $url, $openid ); # 1. If no openid element has been detected $openid = $self->param('openid'); return PE_FIRSTACCESS unless ( $url = $self->param('openIdUrl') or $openid ); # 2. Check OpenID responses if ($openid) { my $csr = $self->{csr}; # Remote error unless ( $csr->is_server_response() ) { $self->{msg} = 'No OpenID valid message found' . $csr->err(); $self->lmLog( $self->{msg}, 'debug' ); return PE_BADCREDENTIALS; } # If confirmation is needed if ( my $setup_url = $csr->user_setup_url ) { $self->lmLog( 'OpenID confirmation needed', 'debug' ); print $self->redirect($setup_url); $self->quit(); } # Check if user has refused to share his authentication elsif ( $csr->user_cancel() ) { $self->{msg} = "OpenID request cancelled by user"; $self->lmLog( $self->{msg}, 'debug' ); return PE_FIRSTACCESS; } # TODO: check verified identity elsif ( $self->{vident} = $csr->verified_identity ) { $self->{user} = $self->{vident}->url(); $self->lmLog( "OpenID good authentication for $self->{user}", 'debug' ); $self->{mustRedirect} = 1; return PE_OK; } # Other errors else { $self->{msg} = 'OpenID error: ' . $csr->err; $self->lmLog( $self->{msg}, 'debug' ); return PE_ERROR; } } # 3. Check if an OpenID url has been submitted else { my $claimed_identity = $self->{csr}->claimed_identity($url); # Check if url is valid unless ($claimed_identity) { $self->{msg} = "OpenID error : " . $self->{csr}->err(); $self->lmLog( $self->{msg}, 'debug' ); return PE_BADCREDENTIALS; } # Redirect user $self->lmLog( "OpenID redirection to $url", 'debug' ); # TODO: insert url=... my $check_url = $claimed_identity->check_url( return_to => $self->{portal} . '?openid=1', trust_root => $self->{portal}, delayed_return => 1, ); print $self->redirect($check_url); $self->quit(); } PE_OK; } ## @apmethod int setAuthSessionInfo() # Set _user and authenticationLevel. # @return Lemonldap::NG::Portal constant sub setAuthSessionInfo { my $self = shift; $self->{sessionInfo}->{'_user'} = $self->{user}; # Since OpenID doesn't share authentication level, falling to 1 $self->{sessionInfo}->{authenticationLevel} = 1; PE_OK; } ## @apmethod int authenticate() # Does nothing. # @return Lemonldap::NG::Portal constant sub authenticate { PE_OK; } ## @apmethod int authFinish() # Does nothing. # @return Lemonldap::NG::Portal constant sub authFinish { PE_OK; } ## @apmethod int authLogout() # Does nothing # @return Lemonldap::NG::Portal constant sub authLogout { PE_OK; } ## @apmethod boolean authForce() # Does nothing # @return result sub authForce { return 0; } 1; __END__ =head1 NAME =encoding utf8 Lemonldap::NG::Portal::AuthOpenID - Perl extension for building Lemonldap::NG compatible portals with OpenID authentication. =head1 SYNOPSIS use Lemonldap::NG::Portal::SharedConf; my $portal = new Lemonldap::NG::Portal::Simple( configStorage => {...}, # See Lemonldap::NG::Portal authentication => 'OpenID', ); if($portal->process()) { # Write here the menu with CGI methods. This page is displayed ONLY IF # the user was not redirected here. print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3)) print "..."; } else { # If the user enters here, IT MEANS THAT CAS REDIRECTION DOES NOT WORK print $portal->header('text/html; charset=utf8'); # DON'T FORGET THIS (see CGI(3)) print "

Unable to work

"; print "This server isn't well configured. Contact your administrator."; print ""; } =head1 DESCRIPTION This library just overload few methods of Lemonldap::NG::Portal::Simple to use OpenID authentication mechanism. See L for usage and other methods. =head1 SEE ALSO L, L, http://wiki.lemonldap.objectweb.org/xwiki/bin/view/NG/Presentation =head1 AUTHOR Thomas Chemineau, Ethomas.chemineau@linagora.comE, Xavier Guimard, Ex.guimard@free.frE =head1 BUG REPORT Use OW2 system to report bug or ask for features: L =head1 DOWNLOAD Lemonldap::NG is available at L =head1 COPYRIGHT AND LICENSE Copyright (C) 2010 Xavier Guimard Ex.guimard@free.frE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available. =cut