Bug 33675: Add CSRF protection to OAuth/OIDC authentication
This patch makes the OAuth/OIDC client pass a `state` parameter with a CSRF protection token, to be validated back when the flow returns to Koha. Ideally, the Mojolicious::Plugin::OAuth2 library should deal with this implicitly, probably making use of JWT. But as of now, this is the best way to implement it. To test: 1. Have a working SSO solution (ktd --sso) 2. Click to login using SSO => SUCCESS: Notice a 'state' parameter on the URL, looks like a random thing 3. When you login, no error is reported Signed-off-by: David Cook <dcook@prosentient.com.au> Signed-off-by: Nick Clemens <nick@bywatersolutions.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
f436bc639c
commit
5d191f21e5
1 changed files with 27 additions and 1 deletions
|
@ -24,6 +24,7 @@ use Mojo::URL;
|
|||
use Scalar::Util qw(blessed);
|
||||
use Try::Tiny;
|
||||
use Koha::Logger;
|
||||
use Koha::Token;
|
||||
use URI::Escape qw(uri_escape_utf8);
|
||||
|
||||
=head1 NAME
|
||||
|
@ -76,7 +77,32 @@ sub login {
|
|||
$provider_config->{authorize_url} = $authorize_url->to_string;
|
||||
}
|
||||
|
||||
return $c->oauth2->get_token_p( $provider, { redirect_uri => $redirect_url . $provider . "/" . $interface } )->then(
|
||||
# Determine if it is a callback request, or the initial
|
||||
my $is_callback = $c->param('error_description') || $c->param('error') || $c->param('code');
|
||||
|
||||
my $state;
|
||||
|
||||
if ($is_callback) {
|
||||
# callback, check CSRF token
|
||||
unless (
|
||||
Koha::Token->new->check_csrf(
|
||||
{
|
||||
session_id => $c->req->cookie('CGISESSID')->value,
|
||||
token => $c->param('state'),
|
||||
}
|
||||
)
|
||||
)
|
||||
{
|
||||
my $error = "wrong_csrf_token";
|
||||
return $c->redirect_to( $uri . "?auth_error=$error" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
# initial request, generate CSRF token
|
||||
$state = Koha::Token->new->generate_csrf( { session_id => $c->req->cookie('CGISESSID')->value } );
|
||||
}
|
||||
|
||||
return $c->oauth2->get_token_p( $provider => { ( !$is_callback ? ( state => $state ) : () ), redirect_uri => $redirect_url . $provider . "/" . $interface } )->then(
|
||||
sub {
|
||||
return unless my $response = shift;
|
||||
|
||||
|
|
Loading…
Reference in a new issue