Manage all proxy workflow for CAS (#101)
This commit is contained in:
parent
b4f5adde99
commit
f4514c41e7
@ -4,11 +4,12 @@ use CGI;
|
||||
use AuthCAS;
|
||||
|
||||
# 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_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 $proxiedService = 'http://webmail';
|
||||
|
||||
# Act as a CAS proxy
|
||||
$cas->proxyMode( pgtFile => '/tmp/pgt.txt', pgtCallbackUrl => $pgtUrl );
|
||||
@ -41,7 +42,7 @@ else {
|
||||
# Ticket receveived
|
||||
else {
|
||||
print $cgi->h1("CAS login done");
|
||||
print $cgi->h2("Received ticket: $ticket");
|
||||
print $cgi->h2("Service ticket: $ticket");
|
||||
|
||||
# Get user
|
||||
my $user = $cas->validateST( $cgi->url(), $ticket );
|
||||
@ -56,17 +57,37 @@ else {
|
||||
my $pgtId = $cas->{pgtId};
|
||||
if ($pgtId) {
|
||||
print $cgi->h2("Proxy granting ticket: $pgtId");
|
||||
|
||||
# Try to request proxy ticket
|
||||
my $pt = $cas->retrievePT($proxiedService);
|
||||
|
||||
if ($pt) {
|
||||
|
||||
print $cgi->h2("Proxy ticket: $pt");
|
||||
|
||||
# Use proxy ticket
|
||||
my ( $puser, @proxies ) =
|
||||
$cas->validatePT( $proxiedService, $pt );
|
||||
|
||||
print $cgi->h2("Proxied user: $puser");
|
||||
print $cgi->h2("Proxies used: @proxies");
|
||||
|
||||
}
|
||||
else {
|
||||
print $cgi->h2( "Error: " . &AuthCAS::get_errors() );
|
||||
}
|
||||
}
|
||||
else {
|
||||
print $cgi->h2("Error: Unable to get proxy granting ticket");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
print $cgi->end_html();
|
||||
|
||||
# Remove PGT file
|
||||
unlink $pgtFile;
|
||||
|
||||
}
|
||||
|
||||
# Remove PGT file
|
||||
unlink $pgtFile;
|
||||
|
||||
exit;
|
||||
|
@ -176,9 +176,14 @@ sub issuerForUnAuthUser {
|
||||
}
|
||||
|
||||
# 4. SERVICE VALIDATE [CAS 2.0]
|
||||
if ( $url =~ /\Q$cas_serviceValidate_url\E/io ) {
|
||||
# 5. PROXY VALIDATE [CAS 2.0]
|
||||
if ( $url =~ /(\Q$cas_serviceValidate_url\E|\Q$cas_proxyValidate_url\E)/io )
|
||||
{
|
||||
|
||||
$self->lmLog( "URL $url detected as an CAS SERVICE VALIDATE URL",
|
||||
my $urlType =
|
||||
( $url =~ /\Q$cas_serviceValidate_url\E/ ? 'SERVICE' : 'PROXY' );
|
||||
|
||||
$self->lmLog( "URL $url detected as an CAS $urlType VALIDATE URL",
|
||||
'debug' );
|
||||
|
||||
# GET parameters
|
||||
@ -198,27 +203,37 @@ sub issuerForUnAuthUser {
|
||||
}
|
||||
|
||||
$self->lmLog(
|
||||
"Get service validate request with ticket $ticket for service $service",
|
||||
"Get "
|
||||
. lc($urlType)
|
||||
. " validate request with ticket $ticket for service $service",
|
||||
'debug'
|
||||
);
|
||||
|
||||
# Get CAS session corresponding to ticket
|
||||
unless ( $ticket =~ s/^ST-// ) {
|
||||
if ( $urlType eq 'SERVICE' and !( $ticket =~ s/^ST-// ) ) {
|
||||
$self->lmLog( "Provided ticket is not a service ticket (ST)",
|
||||
'error' );
|
||||
$self->returnCasServiceValidateError( 'INVALID_TICKET',
|
||||
'Provided ticket is not a service ticket' );
|
||||
}
|
||||
elsif ( $urlType eq 'PROXY' and !( $ticket =~ s/^(P|S)T-// ) ) {
|
||||
$self->lmLog(
|
||||
"Provided ticket is not a service or proxy ticket ($1T)",
|
||||
'error' );
|
||||
$self->returnCasServiceValidateError( 'INVALID_TICKET',
|
||||
'Provided ticket is not a service or proxy ticket' );
|
||||
}
|
||||
|
||||
my $casServiceSession = $self->getCasSession($ticket);
|
||||
|
||||
unless ($casServiceSession) {
|
||||
$self->lmLog( "Service ticket session $ticket not found", 'error' );
|
||||
$self->lmLog( "$urlType ticket session $ticket not found",
|
||||
'error' );
|
||||
$self->returnCasServiceValidateError( 'INVALID_TICKET',
|
||||
'Ticket not found' );
|
||||
}
|
||||
|
||||
$self->lmLog( "Service ticket session $ticket found", 'debug' );
|
||||
$self->lmLog( "$urlType ticket session $ticket found", 'debug' );
|
||||
|
||||
# Check service
|
||||
unless ( $service eq $casServiceSession->{service} ) {
|
||||
@ -246,6 +261,9 @@ sub issuerForUnAuthUser {
|
||||
$self->lmLog( "Renew parameter not managed", 'warn' );
|
||||
}
|
||||
|
||||
# Proxies (for PROXY VALIDATE only)
|
||||
my $proxies = $casServiceSession->{proxies};
|
||||
|
||||
# Proxy granting ticket
|
||||
if ($pgtUrl) {
|
||||
|
||||
@ -258,6 +276,7 @@ sub issuerForUnAuthUser {
|
||||
|
||||
if ($casProxyGrantingSession) {
|
||||
|
||||
# PGT session
|
||||
$casProxyGrantingSession->{type} = 'casProxyGranting';
|
||||
$casProxyGrantingSession->{service} = $service;
|
||||
$casProxyGrantingSession->{_cas_id} =
|
||||
@ -265,10 +284,16 @@ sub issuerForUnAuthUser {
|
||||
$casProxyGrantingSession->{_utime} =
|
||||
$casServiceSession->{_utime};
|
||||
|
||||
# Trace proxies
|
||||
$casProxyGrantingSession->{proxies} =
|
||||
( $proxies
|
||||
? $proxies . $self->{multiValuesSeparator} . $pgtUrl
|
||||
: $pgtUrl );
|
||||
|
||||
my $casProxyGrantingSessionID =
|
||||
$casProxyGrantingSession->{_session_id};
|
||||
my $casProxyGrantingTicket =
|
||||
"TGT-" . $casProxyGrantingSessionID;
|
||||
"PGT-" . $casProxyGrantingSessionID;
|
||||
|
||||
untie %$casProxyGrantingSession;
|
||||
|
||||
@ -344,7 +369,81 @@ sub issuerForUnAuthUser {
|
||||
|
||||
# Return success message
|
||||
$self->returnCasServiceValidateSuccess( $username,
|
||||
$casProxyGrantingTicketIOU );
|
||||
$casProxyGrantingTicketIOU, $proxies );
|
||||
|
||||
# We should not be there
|
||||
return PE_ERROR;
|
||||
}
|
||||
|
||||
# 6. PROXY [CAS 2.0]
|
||||
if ( $url =~ /\Q$cas_proxy_url\E/io ) {
|
||||
|
||||
$self->lmLog( "URL $url detected as an CAS PROXY URL", 'debug' );
|
||||
|
||||
# GET parameters
|
||||
my $pgt = $self->param('pgt');
|
||||
my $targetService = $self->param('targetService');
|
||||
|
||||
# Required parameters: pgt and targetService
|
||||
unless ( $pgt and $targetService ) {
|
||||
$self->lmLog( "Pgt and TargetService parameters required",
|
||||
'error' );
|
||||
$self->returnCasProxyError( 'INVALID_REQUEST',
|
||||
'Missing mandatory parameters (pgt, targetService)' );
|
||||
}
|
||||
|
||||
$self->lmLog(
|
||||
"Get proxy request with ticket $pgt for service $targetService",
|
||||
'debug' );
|
||||
|
||||
# Get CAS session corresponding to ticket
|
||||
unless ( $pgt =~ s/^PGT-// ) {
|
||||
$self->lmLog(
|
||||
"Provided ticket is not a proxy granting ticket (PGT)",
|
||||
'error' );
|
||||
$self->returnCasProxyError( 'BAD_PGT',
|
||||
'Provided ticket is not a proxy granting ticket' );
|
||||
}
|
||||
|
||||
my $casProxyGrantingSession = $self->getCasSession($pgt);
|
||||
|
||||
unless ($casProxyGrantingSession) {
|
||||
$self->lmLog( "Proxy granting ticket session $pgt not found",
|
||||
'error' );
|
||||
$self->returnCasProxyError( 'BAD_PGT', 'Ticket not found' );
|
||||
}
|
||||
|
||||
$self->lmLog( "Proxy granting session $pgt found", 'debug' );
|
||||
|
||||
# Create a proxy ticket
|
||||
$self->lmLog( "Create a CAS proxy ticket for service $targetService",
|
||||
'debug' );
|
||||
|
||||
my $casProxySession = $self->getCasSession();
|
||||
|
||||
unless ($casProxySession) {
|
||||
$self->lmLog( "Unable to create CAS proxy session", 'error' );
|
||||
$self->returnCasProxyError( 'INTERNAL_ERROR',
|
||||
'Error in proxy session management' );
|
||||
}
|
||||
|
||||
$casProxySession->{type} = 'casProxy';
|
||||
$casProxySession->{service} = $targetService;
|
||||
$casProxySession->{_cas_id} = $casProxyGrantingSession->{_cas_id};
|
||||
$casProxySession->{_utime} = $casProxyGrantingSession->{_utime};
|
||||
$casProxySession->{proxies} = $casProxyGrantingSession->{proxies};
|
||||
|
||||
my $casProxySessionID = $casProxySession->{_session_id};
|
||||
my $casProxyTicket = "PT-" . $casProxySessionID;
|
||||
|
||||
# Close sessions
|
||||
untie %$casProxySession;
|
||||
untie %$casProxyGrantingSession;
|
||||
|
||||
$self->lmLog( "CAS proxy session $casProxySessionID created", 'debug' );
|
||||
|
||||
# Return success message
|
||||
$self->returnCasProxySuccess($casProxyTicket);
|
||||
|
||||
# We should not be there
|
||||
return PE_ERROR;
|
||||
@ -496,6 +595,32 @@ sub issuerForAuthUser {
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
# 5. PROXY VALIDATE [CAS 2.0]
|
||||
if ( $url =~ /\Q$cas_proxyValidate_url\E/io ) {
|
||||
|
||||
$self->lmLog( "URL $url detected as an CAS PROXY VALIDATE URL",
|
||||
'debug' );
|
||||
|
||||
# This URL must not be called by authenticated users
|
||||
$self->lmLog(
|
||||
"CAS PROXY VALIDATE URL called by authenticated user, ignore it",
|
||||
'info' );
|
||||
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
# 6. PROXY [CAS 2.0]
|
||||
if ( $url =~ /\Q$cas_proxy_url\E/io ) {
|
||||
|
||||
$self->lmLog( "URL $url detected as an CAS PROXY URL", 'debug' );
|
||||
|
||||
# This URL must not be called by authenticated users
|
||||
$self->lmLog( "CAS PROXY URL called by authenticated user, ignore it",
|
||||
'info' );
|
||||
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
|
@ -89,13 +89,14 @@ sub returnCasServiceValidateError {
|
||||
$self->quit();
|
||||
}
|
||||
|
||||
## @method void returnCasServiceValidateSuccess(string username, string pgtIou)
|
||||
## @method void returnCasServiceValidateSuccess(string username, string pgtIou, string proxies)
|
||||
# Return success for CAS SERVICE VALIDATE request
|
||||
# @param username User name
|
||||
# @param pgtIou Proxy granting ticket IOU
|
||||
# @param proxies List of used CAS proxies
|
||||
# @return nothing
|
||||
sub returnCasServiceValidateSuccess {
|
||||
my ( $self, $username, $pgtIou ) = splice @_;
|
||||
my ( $self, $username, $pgtIou, $proxies ) = splice @_;
|
||||
|
||||
$self->lmLog( "Return CAS service validate success with username $username",
|
||||
'debug' );
|
||||
@ -110,12 +111,60 @@ sub returnCasServiceValidateSuccess {
|
||||
print
|
||||
"\t\t<cas:proxyGrantingTicket>$pgtIou</cas:proxyGrantingTicket>\n";
|
||||
}
|
||||
if ($proxies) {
|
||||
$self->lmLog( "Add proxies $proxies in response", 'debug' );
|
||||
print "\t\t<cas:proxies>\n";
|
||||
print "\t\t\t<cas:proxy>$_</cas:proxy>\n"
|
||||
foreach ( split( /$self->{multiValuesSeparator}/, $proxies ) );
|
||||
print "\t\t</cas:proxies>\n";
|
||||
}
|
||||
print "\t</cas:authenticationSuccess>\n";
|
||||
print "</cas:serviceResponse>\n";
|
||||
|
||||
$self->quit();
|
||||
}
|
||||
|
||||
## @method void returnCasProxyError(string code, string text)
|
||||
# Return an error for CAS PROXY request
|
||||
# @param code CAS error code
|
||||
# @param text Error text
|
||||
# @return nothing
|
||||
sub returnCasProxyError {
|
||||
my ( $self, $code, $text ) = splice @_;
|
||||
|
||||
$code ||= 'INTERNAL_ERROR';
|
||||
$text ||= 'No description provided';
|
||||
|
||||
$self->lmLog( "Return CAS proxy error $code ($text)", 'debug' );
|
||||
|
||||
print $self->header( -type => 'application/xml' );
|
||||
print "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
||||
print "\t<cas:proxyFailure code=\"$code\">\n";
|
||||
print "\t\t$text\n";
|
||||
print "\t</cas:proxyFailure>\n";
|
||||
print "</cas:serviceResponse>\n";
|
||||
|
||||
$self->quit();
|
||||
}
|
||||
|
||||
## @method void returnCasProxySuccess(string ticket)
|
||||
# Return success for CAS PROXY request
|
||||
# @param ticket Proxy ticket
|
||||
# @return nothing
|
||||
sub returnCasProxySuccess {
|
||||
my ( $self, $ticket ) = splice @_;
|
||||
|
||||
$self->lmLog( "Return CAS proxy success with ticket $ticket", 'debug' );
|
||||
|
||||
print $self->header( -type => 'application/xml' );
|
||||
print "<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>\n";
|
||||
print "\t<cas:proxySuccess>\n";
|
||||
print "\t\t<cas:proxyTicket>$ticket</cas:proxyTicket>\n";
|
||||
print "\t</cas:proxySuccess>\n";
|
||||
print "</cas:serviceResponse>\n";
|
||||
|
||||
$self->quit();
|
||||
}
|
||||
## @method boolean deleteCasSecondarySessions(string session_id)
|
||||
# Find and delete CAS sessions bounded to a primary session
|
||||
# @param session_id Primary session ID
|
||||
@ -254,6 +303,14 @@ Return an error for CAS SERVICE VALIDATE request
|
||||
|
||||
Return success for CAS SERVICE VALIDATE request
|
||||
|
||||
=head2 returnCasProxyError
|
||||
|
||||
Return an error for CAS PROXY request
|
||||
|
||||
=head2 returnCasProxySuccess
|
||||
|
||||
Return success for CAS PROXY request
|
||||
|
||||
=head2 deleteCasSession
|
||||
|
||||
Delete an opened CAS session
|
||||
|
Loading…
Reference in New Issue
Block a user