From b4f5adde9961dcb1aeb455d96fbd49c3756dfae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Oudot?= Date: Thu, 26 Aug 2010 14:43:32 +0000 Subject: [PATCH] Manage proxy granting ticket for CAS service validate URL (#101) --- modules/lemonldap-ng-portal/example/cas.pl | 66 ++++++++++++---- .../lib/Lemonldap/NG/Portal/IssuerDBCAS.pm | 75 ++++++++++++++++++- .../lib/Lemonldap/NG/Portal/_CAS.pm | 45 ++++++++++- 3 files changed, 166 insertions(+), 20 deletions(-) diff --git a/modules/lemonldap-ng-portal/example/cas.pl b/modules/lemonldap-ng-portal/example/cas.pl index 99dbc6528..73db656ad 100644 --- a/modules/lemonldap-ng-portal/example/cas.pl +++ b/modules/lemonldap-ng-portal/example/cas.pl @@ -3,34 +3,70 @@ use strict; use CGI; use AuthCAS; -my $cas_url = 'https://auth.example.com/cas'; +# Configuration +my $cas_url = 'https://auth.example.com/cas'; +my $cas = new AuthCAS( casUrl => $cas_url ); +my $cgi = new CGI; +my $pgtUrl = $cgi->url() . "%3Fproxy%3D1"; +my $pgtFile = '/tmp/pgt.txt'; -my $cas = new AuthCAS( casUrl => $cas_url ); -my $cgi = new CGI; +# Act as a CAS proxy +$cas->proxyMode( pgtFile => '/tmp/pgt.txt', pgtCallbackUrl => $pgtUrl ); +# CAS login URL my $login_url = $cas->getServerLoginURL( $cgi->url() ); +# Start HTTP response print $cgi->header(); -print $cgi->start_html('CAS sample client'); -my $ticket = $cgi->param('ticket'); +# Proxy URL for TGT validation +if ( $cgi->param('proxy') ) { -unless ($ticket) { - print $cgi->h1("Click below to use CAS"); - print $cgi->h2("CAS LOGIN"); + # Store pgtId and pgtIou + $cas->storePGT( $cgi->param('pgtIou'), $cgi->param('pgtId') ); } + else { - print $cgi->h1("CAS login done"); - print $cgi->h2("Received ticket: $ticket"); - my $user = $cas->validateST( $cgi->url(), $ticket ); - if ($user) { - print $cgi->h2("Authenticated user: $user"); + + print $cgi->start_html('CAS sample client'); + + my $ticket = $cgi->param('ticket'); + + # First time access + unless ($ticket) { + print $cgi->h1("Click below to use CAS"); + print $cgi->h2("CAS LOGIN"); } + + # Ticket receveived else { - print $cgi->h2("Error: ".&AuthCAS::get_errors()); + print $cgi->h1("CAS login done"); + print $cgi->h2("Received ticket: $ticket"); + + # Get user + my $user = $cas->validateST( $cgi->url(), $ticket ); + if ($user) { + print $cgi->h2("Authenticated user: $user"); + } + else { + print $cgi->h2( "Error: " . &AuthCAS::get_errors() ); + } + + # Get proxy granting ticket + my $pgtId = $cas->{pgtId}; + if ($pgtId) { + print $cgi->h2("Proxy granting ticket: $pgtId"); + } + else { + print $cgi->h2("Error: Unable to get proxy granting ticket"); + } } + + print $cgi->end_html(); + } -print $cgi->end_html(); +# Remove PGT file +unlink $pgtFile; exit; diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBCAS.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBCAS.pm index 389204b63..af4c1d664 100644 --- a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBCAS.pm +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/IssuerDBCAS.pm @@ -187,6 +187,9 @@ sub issuerForUnAuthUser { my $pgtUrl = $self->param('pgtUrl'); my $renew = $self->param('renew'); + # PGTIOU + my $casProxyGrantingTicketIOU; + # Required parameters: service and ticket unless ( $service and $ticket ) { $self->lmLog( "Service and Ticket parameters required", 'error' ); @@ -246,9 +249,74 @@ sub issuerForUnAuthUser { # Proxy granting ticket if ($pgtUrl) { + # Create a proxy granting ticket + $self->lmLog( + "Create a CAS proxy granting ticket for service $service", + 'debug' ); + + my $casProxyGrantingSession = $self->getCasSession(); + + if ($casProxyGrantingSession) { + + $casProxyGrantingSession->{type} = 'casProxyGranting'; + $casProxyGrantingSession->{service} = $service; + $casProxyGrantingSession->{_cas_id} = + $casServiceSession->{_cas_id}; + $casProxyGrantingSession->{_utime} = + $casServiceSession->{_utime}; + + my $casProxyGrantingSessionID = + $casProxyGrantingSession->{_session_id}; + my $casProxyGrantingTicket = + "TGT-" . $casProxyGrantingSessionID; + + untie %$casProxyGrantingSession; + + $self->lmLog( +"CAS proxy granting session $casProxyGrantingSessionID created", + 'debug' + ); + + # Generate the proxy granting ticket IOU + my $tmpCasSession = $self->getCasSession(); + + if ($tmpCasSession) { + + $casProxyGrantingTicketIOU = + "PGTIOU-" . $tmpCasSession->{_session_id}; + $self->deleteCasSession($tmpCasSession); + $self->lmLog( +"Generate proxy granting ticket IOU $casProxyGrantingTicketIOU", + 'debug' + ); + # Request pgtUrl - # TODO - $self->lmLog( "PgtUrl parameter not managed", 'warn' ); + if ( + $self->callPgtUrl( + $pgtUrl, + $casProxyGrantingTicketIOU, + $casProxyGrantingTicket + ) + ) + { + $self->lmLog( + "Proxy granting URL $pgtUrl called with success", + 'debug' ); + } + else { + $self->lmLog( + "Error calling proxy granting URL $pgtUrl", + 'warn' ); + $casProxyGrantingTicketIOU = undef; + } + } + + } + else { + $self->lmLog( + "Error in proxy granting ticket management, bypass it", + 'warn' ); + } } # Open local session @@ -275,7 +343,8 @@ sub issuerForUnAuthUser { untie %$localSession; # Return success message - $self->returnCasServiceValidateSuccess($username); + $self->returnCasServiceValidateSuccess( $username, + $casProxyGrantingTicketIOU ); # We should not be there return PE_ERROR; diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_CAS.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_CAS.pm index 4e0c4e90d..2c7bf46d3 100644 --- a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_CAS.pm +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_CAS.pm @@ -6,6 +6,7 @@ package Lemonldap::NG::Portal::_CAS; use strict; +use LWP::UserAgent; our $VERSION = '0.01'; @@ -88,12 +89,13 @@ sub returnCasServiceValidateError { $self->quit(); } -## @method void returnCasServiceValidateSuccess(string username) +## @method void returnCasServiceValidateSuccess(string username, string pgtIou) # Return success for CAS SERVICE VALIDATE request # @param username User name +# @param pgtIou Proxy granting ticket IOU # @return nothing sub returnCasServiceValidateSuccess { - my ( $self, $username ) = splice @_; + my ( $self, $username, $pgtIou ) = splice @_; $self->lmLog( "Return CAS service validate success with username $username", 'debug' ); @@ -102,6 +104,12 @@ sub returnCasServiceValidateSuccess { print "\n"; print "\t\n"; print "\t\t$username\n"; + if ( defined $pgtIou ) { + $self->lmLog( "Add proxy granting ticket $pgtIou in response", + 'debug' ); + print + "\t\t$pgtIou\n"; + } print "\t\n"; print "\n"; @@ -172,6 +180,35 @@ sub deleteCasSession { return 1; } +## @method boolean callPgtUrl(string pgtUrl, string pgtIou, string pgtId) +# Call proxy granting URL on CAS client +# @param pgtUrl Proxy granting URL +# @param pgtIou Proxy granting ticket IOU +# @param pgtId Proxy granting ticket +# @return result +sub callPgtUrl { + my ( $self, $pgtUrl, $pgtIou, $pgtId ) = splice @_; + + # LWP User Agent + my $ua = new LWP::UserAgent; + push @{ $ua->requests_redirectable }, 'POST'; + $ua->env_proxy(); + + # Build URL + my $url = $pgtUrl; + $url .= ( $pgtUrl =~ /\?/ ? '&' : '?' ); + $url .= "pgtIou=$pgtIou&pgtId=$pgtId"; + + $self->lmLog( "Call URL $url", 'debug' ); + + # GET URL + my $response = $ua->get($url); + + # Return result + return $response->is_success(); + +} + 1; __END__ @@ -221,6 +258,10 @@ Return success for CAS SERVICE VALIDATE request Delete an opened CAS session +=head2 callPgtUrl + +Call proxy granting URL on CAS client + =head1 SEE ALSO L