Bug 36084: Add CSRF token support to svc/authentication
GET svc/authentication will return a CSRF token in a response header POST svc/authentication requires a CSRF token which can be sourced from the response header of GET svc/authentication or some other place like the meta element on a HTML page Note: misc/migration_tools/koha-svc.pl is a simple script which can be used to practically evaluate svc/authentication and svc/bib Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
parent
61f1f88c5c
commit
0fe82b601b
3 changed files with 37 additions and 11 deletions
|
@ -1602,7 +1602,7 @@ sub check_api_auth {
|
|||
}
|
||||
|
||||
my ( $sessionID, $session );
|
||||
unless ( $query->param('userid') ) {
|
||||
unless ( $query->param('login_userid') ) {
|
||||
$sessionID = $query->cookie("CGISESSID");
|
||||
}
|
||||
if ( $sessionID && not( $cas && $query->param('PT') ) ) {
|
||||
|
|
|
@ -104,7 +104,15 @@ sub new {
|
|||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
$ua->cookie_jar({});
|
||||
my $resp = $ua->post( "$url/authentication", {userid =>$user, password => $password} );
|
||||
|
||||
my $get_resp = $ua->get("$url/authentication");
|
||||
my $csrf_token = $get_resp->header('X-CSRF-TOKEN');
|
||||
$self->{csrf_token} = $csrf_token;
|
||||
|
||||
my $resp = $ua->post(
|
||||
"$url/authentication",
|
||||
{ login_userid => $user, login_password => $password, csrf_token => $csrf_token }
|
||||
);
|
||||
die $resp->status_line unless $resp->is_success;
|
||||
|
||||
warn "# $user $url = ", $resp->decoded_content, "\n" if $self->{debug};
|
||||
|
@ -140,7 +148,11 @@ sub post {
|
|||
my ($self,$biblionumber,$marcxml) = @_;
|
||||
my $url = $self->{url};
|
||||
warn "# post $url/bib/$biblionumber\n" if $self->{debug};
|
||||
my $resp = $self->{ua}->post( "$url/bib/$biblionumber", 'Content_type' => 'text/xml', Content => $marcxml );
|
||||
my $csrf_token = $self->{csrf_token};
|
||||
my $resp = $self->{ua}->post(
|
||||
"$url/bib/$biblionumber", 'Content_type' => 'text/xml', Content => $marcxml,
|
||||
csrf_token => $csrf_token
|
||||
);
|
||||
die $resp->status_line unless $resp->is_success;
|
||||
return $resp->decoded_content;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
use Modern::Perl;
|
||||
|
||||
use CGI qw ( -utf8 );
|
||||
use C4::Auth qw/check_api_auth/;
|
||||
use C4::Auth qw/check_api_auth get_session/;
|
||||
use XML::Simple;
|
||||
|
||||
my $query = CGI->new;
|
||||
|
@ -41,12 +41,26 @@ my $query = CGI->new;
|
|||
# 3. The session cookie should not be (directly) sent back to the user's
|
||||
# web browser, but instead should be stored and submitted by biblios.
|
||||
|
||||
|
||||
my ($status, $cookie, $sessionID) = check_api_auth($query, { editcatalogue => 'edit_catalogue'} );
|
||||
|
||||
if ($status eq "ok") {
|
||||
print $query->header(-type => 'text/xml', cookie => $cookie);
|
||||
my $csrf_token;
|
||||
my ( $status, $cookie, $sessionID ) = check_api_auth( $query, { editcatalogue => 'edit_catalogue' } );
|
||||
if ( $status eq "ok" ) {
|
||||
$csrf_token = Koha::Token->new->generate_csrf( { session_id => scalar $sessionID } );
|
||||
} else {
|
||||
print $query->header(-type => 'text/xml');
|
||||
my $session = C4::Auth::get_session("");
|
||||
$session->param( 'ip', $session->remote_addr() );
|
||||
$session->param( 'lasttime', time() );
|
||||
$session->param( 'sessiontype', 'anon' );
|
||||
$session->param( 'interface', 'api' );
|
||||
$session->flush();
|
||||
$sessionID = $session->id();
|
||||
$cookie = $query->cookie(
|
||||
-name => 'CGISESSID',
|
||||
-value => $sessionID,
|
||||
-HttpOnly => 1,
|
||||
-secure => ( C4::Context->https_enabled() ? 1 : 0 ),
|
||||
-sameSite => 'Lax'
|
||||
);
|
||||
$csrf_token = Koha::Token->new->generate_csrf( { session_id => scalar $sessionID } );
|
||||
}
|
||||
print XMLout({ status => $status }, NoAttr => 1, RootName => 'response', XMLDecl => 1);
|
||||
print $query->header( -type => 'text/xml', cookie => $cookie, -'X-CSRF_TOKEN' => $csrf_token );
|
||||
print XMLout( { status => $status }, NoAttr => 1, RootName => 'response', XMLDecl => 1 );
|
||||
|
|
Loading…
Reference in a new issue