# Plugin to remember which authentication method has been chosen,
# and laun it automatically
use strict;
use Mouse;
PE_OK
PE_SENDRESPONSE
);
our $VERSION = '2.20.0';
# INTERFACE
use constant endAuth => 'storeRememberedAuthChoice';
use constant beforeAuth => 'checkRememberedAuthChoice';
use constant beforeLogout => 'removeRememberedAuthChoice';
use constant hook => { getAuthChoice => "autoChoice", };
has rule => ( is => 'rw', default => sub { 0 } );
has rememberCookieName => (
is => 'ro',
lazy => 1,
default => sub {
$_[0]->conf->{rememberCookieName} // 'llngrememberauthchoice';
}
);
# Default timeout: 1 year
has rememberCookieTimeout => (
is => 'ro',
lazy => 1,
default => sub {
$_[0]->conf->{rememberCookieTimeout} // 31536000;
}
);
sub init {
my ($self) = @_;
# Parse activation rule
$self->rule(
$self->p->buildRule(
$self->conf->{rememberAuthChoiceRule},
'rememberAuthChoiceRule'
)
);
return 0 unless $self->rule;
return 1;
}
sub storeRememberedAuthChoice {
my ( $self, $req ) = @_;
# Get directly authentication choice from sessionInfo
my $lmAuth = $req->sessionInfo->{_choice};
# Get rememberauthchoice tick from corresponding hash
# * req->pdata for Issuer auth modules (SAML, OIDC,...)
# * req->data for direct auth modules (LDAP)
my $rememberauthchoice =
$req->pdata->{rememberauthchoice}
|| $req->data->{rememberauthchoice}
|| "";
if ($lmAuth) {
# Store cookie to remember the authentication choice
if ( $rememberauthchoice eq "true" ) {
$self->logger->warn( "RememberAuthChoice: set cookie "
. $self->rememberCookieName
. " with authentication choice lmAuth="
. $lmAuth );
$req->addCookie(
$self->p->cookie(
name => $self->rememberCookieName,
value => $lmAuth,
max_age => $self->rememberCookieTimeout,
secure => $self->conf->{securedCookie},
HttpOnly => 0, # required for cookie to be read by js
)
);
}
# Remove cookie to forget previous authentication choice
else {
$self->logger->warn( "RememberAuthChoice: Remove cookie "
. $self->rememberCookieName );
$req->addCookie(
$self->p->cookie(
name => $self->rememberCookieName,
value => 0,
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
secure => $self->conf->{securedCookie},
)
);
# Avoid regressions with #3228
$req->addCookie(
$self->p->genDomainCookie(
$req,
name => $self->rememberCookieName,
value => 0,
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
secure => $self->conf->{securedCookie},
)
);
}
}
return PE_OK;
}
sub checkRememberedAuthChoice {
my ( $self, $req ) = @_;
# Check if form has been sent with a rememberauthchoice tick
my $lmAuth = $req->param('lmAuth') || "";
my $rememberauthchoice = $req->param('rememberauthchoice') || "";
# If so, store rememberauthchoice tick for the endAuth endpoint
if ($lmAuth) {
# For authentication method occurring in the same request
$req->data->{rememberauthchoice} = $rememberauthchoice;
# For authentication method occurring in a different request
$req->pdata->{rememberauthchoice} = $rememberauthchoice;
}
return PE_OK;
}
sub removeRememberedAuthChoice {
my ( $self, $req ) = @_;
if ( $self->conf->{rememberAuthChoiceForgetAtLogout} ) {
$self->logger->debug( "RememberAuthChoice: Remove cookie "
. $self->rememberCookieName
. " at logout" );
$req->addCookie(
$self->p->cookie(
name => $self->rememberCookieName,
value => 0,
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
secure => $self->conf->{securedCookie},
)
);
# Avoid regressions with #3228
$req->addCookie(
$self->p->genDomainCookie(
$req,
name => $self->rememberCookieName,
value => 0,
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
secure => $self->conf->{securedCookie},
)
);
}
return PE_OK;
}
sub autoChoice {
my ( $self, $req, $context ) = @_;
if ( my $choice = $req->cookies->{ $self->rememberCookieName }
and $self->conf->{rememberTimer} == 0 )
{
$context->{choice} = $choice;
# Continue remembering the choice
$req->pdata->{rememberauthchoice} = "true";
}
return PE_OK;
}
1;