Bug 42719: Handle missing CGISESSID in OAuth login (IdP-initiated flow)
When a user initiates login from the IdP (e.g. Okta app tile), they hit the OAuth endpoint without an existing session cookie. The code crashed calling ->value on an undefined cookie object. This patch: - Removes the premature 'No user session found' guard that blocked IdP-initiated flows entirely - Creates a session on-the-fly for the initial request when no cookie exists (IdP-initiated flow) - On callback, redirects with wrong_csrf_token error instead of crashing when the cookie is missing CSRF protection is preserved: the state token is bound to the session created in the initial request, and the browser returns the cookie on callback for validation. Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: David Nind <david@davidnind.com> Signed-off-by: David Cook <dcook@prosentient.com.au> Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
fda4343019
commit
9eaeae69e5
|
|
@ -66,10 +66,11 @@ sub login {
|
||||||
}
|
}
|
||||||
|
|
||||||
my $current_session;
|
my $current_session;
|
||||||
|
my $session_id;
|
||||||
my $current_session_cookie = $c->req->cookie('CGISESSID');
|
my $current_session_cookie = $c->req->cookie('CGISESSID');
|
||||||
if ($current_session_cookie) {
|
if ($current_session_cookie) {
|
||||||
my $current_session_id = $current_session_cookie->value;
|
$session_id = $current_session_cookie->value;
|
||||||
$current_session = Koha::Session->get_session( { sessionID => $current_session_id } );
|
$current_session = Koha::Session->get_session( { sessionID => $session_id } );
|
||||||
}
|
}
|
||||||
|
|
||||||
unless ( $provider_config && $provider_config->{authorize_url} ) {
|
unless ( $provider_config && $provider_config->{authorize_url} ) {
|
||||||
|
|
@ -77,11 +78,6 @@ sub login {
|
||||||
return $c->redirect_to( $uri . "?auth_error=$error" );
|
return $c->redirect_to( $uri . "?auth_error=$error" );
|
||||||
}
|
}
|
||||||
|
|
||||||
unless ($current_session_cookie) {
|
|
||||||
my $error = "No user session found";
|
|
||||||
return $c->redirect_to( $uri . "?auth_error=$error" );
|
|
||||||
}
|
|
||||||
|
|
||||||
unless ( $provider_config->{authorize_url} =~ /response_type=code/ ) {
|
unless ( $provider_config->{authorize_url} =~ /response_type=code/ ) {
|
||||||
my $authorize_url = Mojo::URL->new( $provider_config->{authorize_url} );
|
my $authorize_url = Mojo::URL->new( $provider_config->{authorize_url} );
|
||||||
$authorize_url->query->append( response_type => 'code' );
|
$authorize_url->query->append( response_type => 'code' );
|
||||||
|
|
@ -96,10 +92,15 @@ sub login {
|
||||||
if ($is_callback) {
|
if ($is_callback) {
|
||||||
|
|
||||||
# callback, check CSRF token
|
# callback, check CSRF token
|
||||||
|
unless ($session_id) {
|
||||||
|
my $error = "wrong_csrf_token";
|
||||||
|
return $c->redirect_to( $uri . "?auth_error=$error" );
|
||||||
|
}
|
||||||
|
|
||||||
unless (
|
unless (
|
||||||
Koha::Token->new->check_csrf(
|
Koha::Token->new->check_csrf(
|
||||||
{
|
{
|
||||||
session_id => $current_session_cookie->value,
|
session_id => $session_id,
|
||||||
token => $c->param('state'),
|
token => $c->param('state'),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -110,8 +111,14 @@ sub login {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
# initial request, generate CSRF token
|
# initial request — create session if needed (IdP-initiated flow)
|
||||||
$state = Koha::Token->new->generate_csrf( { session_id => $current_session_cookie->value } );
|
unless ($session_id) {
|
||||||
|
$current_session = Koha::Session->get_session( {} );
|
||||||
|
$session_id = $current_session->id;
|
||||||
|
$c->cookie( CGISESSID => $session_id, { path => '/' } );
|
||||||
|
}
|
||||||
|
|
||||||
|
$state = Koha::Token->new->generate_csrf( { session_id => $session_id } );
|
||||||
|
|
||||||
Koha::Auth::Identity::Referer->store_referer(
|
Koha::Auth::Identity::Referer->store_referer(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue