Apache2-AuthCASpbh
view release on metacpan or search on metacpan
lib/Apache2/AuthCASpbh/Authn.pm view on Meta::CPAN
if (exists($session->{cas_proxy})) {
$_log->l($debug_level, 'session contains proxy chain ' .
join(',', @{$session->{cas_proxy}}));
$r->pnotes(cas_proxy => $session->{cas_proxy});
}
$cookies{$cookie_name}->bake($r);
$r->pnotes(cas_session => $session->{_session_id});
untie(%{$session});
return Apache2::Const::OK;
}
else {
$_log->l($debug_level, 'cookie for ' . ($session->{user} // '<missing>') .
' expired ' . ($session->{expiration} // '<missing>'));
eval { tied(%{$session})->delete; };
if ($@) {
$_log->l('warn', "session delete failed - $@");
}
}
}
elsif ($session !~ /Object does not exist in the data store/) {
$_log->l('error', "session tie failed - $session");
return Apache2::Const::SERVER_ERROR;
}
else {
$_log->l($debug_level, "session not found");
}
}
else {
$_log->l($debug_level, "$cookie_name cookie not found");
}
my $q = CGI->new($r, $r->args);
my $qs_nt = $r->args // '';
if ($qs_nt) {
$qs_nt =~ s/(^|&)ticket=[^&]+(&|$)/$1$2/;
$qs_nt =~ s/(^&|&&|&$)//;
}
my $service;
if (defined(cfg_value($dir_cfg, 'ServiceOverride'))) {
$service = cfg_value($dir_cfg, 'ServiceOverride');
$_log->l($debug_level, "overriding service to $service");
}
else {
$service = $r->construct_url() . ($qs_nt ? "?$qs_nt" : '');
$_log->l($debug_level, "set service to $service");
};
$service = Apache2::Util::escape_path($service, $r->pool);
my $st = $q->param('ticket');
if ($st) {
my $ua = LWP::UserAgent->new(timeout => 10, keep_alive => 1);
my $proxy_allow = cfg_value($dir_cfg, 'ProxyAllow');
my $proxy_allow_re = cfg_value($dir_cfg, 'ProxyAllowRE');
my $validate_url = cfg_value($dir_cfg, 'ServerURL') .
(defined($proxy_allow) || defined($proxy_allow_re) ?
cfg_value($dir_cfg, 'ProxyValidatePath') :
cfg_value($dir_cfg, 'ServiceValidatePath')) .
"?service=$service&ticket=$st";
$_log->l($debug_level, "validating via URL $validate_url");
if (cfg_value($dir_cfg, 'RequestPGT')) {
my $pgt_callback = cfg_value($dir_cfg, 'PGTCallback');
if ($pgt_callback !~ m#^https://#) {
$pgt_callback = 'https://' . $r->server->server_hostname .
$pgt_callback;
}
$_log->l($debug_level, "using PGT callback $pgt_callback");
$pgt_callback = Apache2::Util::escape_path($pgt_callback, $r->pool);
$validate_url .= "&pgtUrl=$pgt_callback";
}
my $response;
$response = $ua->get($validate_url);
if(!$response->is_success()) {
$_log->l('error', 'ticket validation call failed - ' .
$response->status_line());
return Apache2::Const::SERVER_ERROR;
}
my $cas_data = eval { XML::Simple::XMLin($response->content(),
ForceArray => [ 'cas:proxy' ]); };
if ($@) {
$_log->l('error', "ticket validation xml parse failed - $@");
return Apache2::Const::SERVER_ERROR;
}
if (exists($cas_data->{'cas:authenticationSuccess'})) {
my $cas_success = $cas_data->{'cas:authenticationSuccess'};
my $user = $cas_success->{'cas:user'};
$_log->l($debug_level, "validated user $user");
$r->user($user);
my $cas_proxy;
if (defined($proxy_allow) || defined($proxy_allow_re)) {
if (exists($cas_success->{'cas:proxies'}{'cas:proxy'})) {
$cas_proxy = $cas_success->{'cas:proxies'}{'cas:proxy'};
if (!_allowed_proxy($_log, $debug_level, $cas_proxy,
$proxy_allow, $proxy_allow_re)) {
$_log->l('notice', 'proxy chain (' .
join(' ', @{$cas_proxy}) .
') not permitted');
return Apache2::Const::FORBIDDEN;
}
$_log->l($debug_level, 'proxied via ' .
join(' ', @{$cas_proxy}));
$r->pnotes(cas_proxy => $cas_proxy);
}
elsif (cfg_value($dir_cfg, 'ProxyRequired')) {
$_log->l('notice', 'proxy chain not found in response');
return Apache2::Const::FORBIDDEN;
}
}
my $pgt;
if (cfg_value($dir_cfg, 'RequestPGT')) {
if (exists($cas_success->{'cas:proxyGrantingTicket'})) {
my $pgt_iou = $cas_success->{'cas:proxyGrantingTicket'};
my $pgt_session = open_session($session_db,
cfg_value($dir_cfg, 'SessionStateName'));
$_log->l($debug_level, 'opening global state session ' .
cfg_value($dir_cfg, 'SessionStateName'));
if (!ref($pgt_session)) {
if ($pgt_session =~ /Object does not exist in the data store/) {
$_log->l('error', 'global state session must be pre-created');
}
else {
$_log->l('error', "session tie failed - $pgt_session");
}
return Apache2::Const::SERVER_ERROR;
}
if (exists($pgt_session->{pgtmap}{$pgt_iou})) {
$pgt = $pgt_session->{pgtmap}{$pgt_iou}{pgt};
$_log->l($debug_level, "found pgt $pgt");
delete($pgt_session->{pgtmap}{$pgt_iou});
$pgt_session->{update_count}++;
untie(%{$pgt_session});
$r->pnotes(cas_pgt => $pgt);
}
else {
$_log->l('error', "pgt for $pgt_iou not found in session");
return Apache2::Const::SERVER_ERROR;
}
}
( run in 1.745 second using v1.01-cache-2.11-cpan-437f7b0c052 )