Eroln has asked for the wisdom of the Perl Monks concerning the following question:

Reason

I am trying to change JIRA::Client::Automated to use cookie authentication instead of basic_auth(user/password). It is requested by admins as basic authentication is overloading AD.

I should add that code is fully functional when running with basic authentication. The main change is in "new" method. Here I add a line with cookie jar & removed basic authentications.

sub new_c { my ($class, $url, $cookie) = @_; my $self = { url => $url, auth_url => $auth_url }; bless $self, $class; $self->{_ua} = LWP::UserAgent->new(); $self->{_ua}->cookie_jar({cookies => $cookie} ); return $self; }
Cookie to the code is supplied in the form of text: JSESSIONID=F97AC6F5AD33D54D0C06F4CBF0230C43 in JSON cookie jar is visible:
$VAR1 = bless( { '_ua' => bless( { 'cookie_jar' => 'JSESSIONID=F97AC6F +5AD33D54D0C06F4CBF0230C43', }, 'LWP::UserAgent' ), }
Then I post GET request and answer is 401 error.
garbage after JSON object, at character offset 4 (before "Can't locate + object .. .") at C:/strawberry/perl/site/lib//JIRA/Client/Automated.pm line 385. request GET /rest/api/latest/issue/JIML-3044: at main.pl line 30 response 401 Unauthorized: {"errorMessages":["You do not have the perm +ission to see the specified issue.","Login Required"],"errors":{}} at main.pl li +ne 30 Unable to GET /rest/api/latest/issue/JIML-3044: 401 Unauthorized{ errorMessages => [ "You do not have the permission to see the specified issue.", "Login Required", ], errors => {}, }
I suspect I messed correct cookie jar writing, but out of ideas how to write it.

Note, I have access rights for the issue, the cookie itself is functional - both checked using curl. Any idea to supply cookie to cookie_jar to be usable?

There is very similar question in monastery: http://www.perlmonks.org/?node_id=456612, but it was not answered in a way I can use.

Replies are listed 'Best First'.
Re: what is the correct way to set cookie in LWP::UserAgent
by Corion (Patriarch) on Jun 14, 2017 at 09:38 UTC
      Thanks for the answer, of course.

      I looked in LWP::UserAgent previously and I still hope I can supply just a string with cookie itself, not cookies.lwp file. Basic question - is it possible?

      In HTTP::Cookies is mentioned I should supply cookie from a file. Which I hoped to avoid...

      As plan B, I will try to create lwp cookies. But it is Catch XXII, no knowledge of structure-> no cookie-> not functional connection-> no updated cookie, thus no connection. But that might be another question, I haven't searched for answer yet.

        A cookie is just another header. A cookie jar is a collection of cookies that the browser can search by the page it is going to and select the right ones to send back

        if you wanted to just supply a single cookie and not care about any cookies you get back you could try this

        my $ua=LWP::UserAgent->new(keep_alive=>1); my $getline='http://place.to.go.to/'; my $req = new HTTP::Request (GET => $getline ,HTTP::Headers->new('Cookie'=> 'JSESSION +ID=F97AC6F5AD33D54D0C06F4CBF0230C43' ) ); my $request = $ua->request ($req);
        When i want to use a "stand alone" cookie-jar i do something like this
        my $cookie_jar_obj = HTTP::Cookies->new(ignore_discard=>1,hide_cooki +e2=>1); my $ua=LWP::UserAgent->new(keep_alive=>1); $ua->cookie_jar( $cookie_jar_obj ); $cookie_jar_obj->set_cookie(0, 'JSESSIONID', 'F97AC6F5AD33D54D0C06F4 +CBF0230C43' , '/', 'place.to.go.to', 80 , '', '', 14400000, 0 ); $cookie_jar_obj->set_cookie(0, 'LoginUsername', 'Operator' , '/', 'place.to.go.to', 80 , '', '', 14400000, 0 ); $cookie_jar_obj->set_cookie(0, "LoginPassword", 'Operator' , '/', 'place.to.go.to', 80 , '', '', 14400000, 0 ); $repeatme=1; while ($repeatme) { my $getline='http://place.to.go.to/'; my $req = new HTTP::Request (GET => $getline); my $request = $ua->request ($req); if (some-test-for-done){ $repeatme=0;} }
        In both cases those are just cut and pastes from existing code and not tested as they appear here. YMMV

Re: what is the correct way to set cookie in LWP::UserAgent
by Eroln (Novice) on Jun 21, 2017 at 01:28 UTC

    It feels strange to answer to myself. But here is an answer which describes the best my original problem.

  • It is not possible to transfer cookies between 'agents'. That means if you get cookie via curl, you cannot supply it back to JIRA/REST via LWP.
  • Use cURL to retrieve original cookie? Then continue with cURL. If you plan to use LWP or JIRA::Client::Automated, like me, get cookie via this agent. See following code:

    use LWP::UserAgent; use HTTP::Request; my $user = "JIRAusername"; my $password = "Lamepassword"; my $jira_url = "put_your_server_here"; my $ck=LWP::UserAgent->new( ); my $getline= $jira_url . '/jiraurl/rest/auth/1/session'; my $request = new HTTP::Request (GET => $getline, HTTP::Headers->new(' +Content_Type' => 'application/json') ); $request->authorization_basic($user, $password); my $answer = $ck->request ($request); my $cookie = $answer->header('Set-Cookie');
    The very last line gave me a lot of grey hair, so enjoy it, please. Now you have all cookies in variable. JIRA gives me normal 'JSESSION cookie' and token together. Authentication was NOT functional in case I have used only one of them.
  • Second pitfall - where and how to put cookie? I mean as a part of JIRA request.
  • Following piece of code is showing easy way to use it. I have created another lwp agent, just to show cookie is functional for independent one.
    my $ua=LWP::UserAgent->new( keep_alive => 1 ); my $key = 'existing_issue_code'; #this is just for test. You can use a +ny issue you get from web JIRA $getline=$url . '/rest/api/latest/issue/' . $key; $request = new HTTP::Request (GET => $getline, HTTP::Headers->new('Coo +kie'=> $cookie ) ); $answer = $ua->request ($request);
    Then just test return value, it shall be 200 and enjoy...

    I will spend some time by debugging of updated version of JIRA::Client::Automated and post it on CPAN later.