Apache-AuthCASSimple
view release on metacpan or search on metacpan
lib/Apache/AuthCASSimple.pm view on Meta::CPAN
#
# handler()
#
# Called by apache/mod_perl
#
sub handler ($) {
my $r = shift;
my $log = $r->log();
# does it need to do something ?
return DECLINED unless($r->auth_type() eq __PACKAGE__);
$log->info(__PACKAGE__.": Entering into authentification process.:".$r->uri() ."--".$r->args());
# Get module config (Apache directive values)
my $cfg = Apache::ModuleConfig->get($r, __PACKAGE__);
# Check for internal session
my $user;
if($cfg->{_cas_session_timeout} >= 0 && ($user = _get_user_from_session($r))) {
$log->info(__PACKAGE__.": Session found for user $user.");
$r->connection->user($user);
return OK;
}
elsif($cfg->{_cas_session_timeout} >= 0) {
$log->info(__PACKAGE__.": No session found.");
}
else {
$log->info(__PACKAGE__.": Session disabled.");
}
# instance CAS object
my ($cas, %options);
$options{casUrl} = ($cfg->{_cas_ssl} ? 'https://' : 'http://').$cfg->{_cas_name}.':'.$cfg->{_cas_port}.$cfg->{_cas_path};
# $options{CAFile} = $cfg->{_ca_file} if ($cfg->{_cas_ssl});
unless($cas = Authen::CAS::Client->new($options{casUrl}, fatal => 1)) {
$log->error(__PACKAGE__.": Unable to create CAS instance.");
return SERVER_ERROR;
}
my $requested_url = _get_requested_url($r,$cfg);
my $login_url = $requested_url;
# TODO better clean url
$login_url =~ s/\?/\&/;
$login_url = $cas->login_url().$login_url;
# redirect to CAS server unless ticket parameter
my %args = $r->args();
unless ($args{ticket}) {
$log->info(__PACKAGE__.": No ticket, client redirected to CAS server.");
$r->err_header_out("Location" => $login_url);
return REDIRECT;
}
# Validate the ticket we received
if ($args{ticket}=~/^PT/) {
my $r = $cas->proxy_validate( $requested_url, $args{ticket} );
if( $r->is_success() ) {
$user=$r->user();
$log->warn(__PACKAGE__.": Validate PT on CAS Proxy server. ".join ",", $r->proxies());
};
}
else {
my $r = $cas->service_validate( $requested_url, $args{ticket} );
if ( $r->is_success() ) {
$user = $r->user();
}
}
unless ($user) {
$log->warn(__PACKAGE__.": Unable to validate ticket ".$args{ticket}." on CAS server.");
$r->err_header_out("Location" => $login_url);
return REDIRECT;
#return FORBIDDEN;
}
$log->info(__PACKAGE__.": Ticket ".$args{ticket}." succesfully validated.");
if ( $user ) {
$r->connection->user($user);
$log->info(__PACKAGE__.": New session ".$r->uri() ."--".$r->args());
# if we are there (and timeout is set), we can create session data and cookie
_remove_ticket($r);
_create_user_session($r) if($cfg->{_cas_session_timeout} >= 0);
$r->err_header_out("Location" => $r->uri . ($r->args ? '?' . $r->args : '') );
# if session, redirect remove ticket in url
return ($cfg->{_cas_session_timeout} >= 0)?REDIRECT:OK;
}
return FORBIDDEN;
}
#
# _get_requested_url()
#
# Return the URL requested by client (with args)
#
sub _get_requested_url ($$) {
my $r = shift;
my $cfg = shift;
my $port = $r->get_server_port();
my $is_https = $r->subprocess_env('https') ? 1 : 0;
my $url = $is_https ? 'https://' : 'http://';
$url .= $r->hostname();
$url .= ':'.$port if (!$cfg->{_mod_proxy} && ( ($is_https && $port != 443) || (!$is_https && $port != 80) ));
$url .= $r->uri()._get_query_string($r);
return $url;
}
#
# _get_query_string()
#
# Return the query string
#
sub _get_query_string ($) {
my $r = shift;
_post_to_get($r) if ($r->method eq 'POST');
my %args = $r->args();
my @qs = ();
foreach (sort {$a cmp $b} keys(%args)) {
next if ($_ eq 'ticket');
push(@qs, $_."=".$args{$_});
}
return $#qs != -1 ? "?".join("\&", @qs) : "";
}
#
( run in 1.256 second using v1.01-cache-2.11-cpan-140bd7fdf52 )