Login to IBM Rational Quality Manager server application with FORM-BASED authetication

686 views Asked by At

I can not understand what I'm doing wrong when trying to login to IBM Rational Quality Manager from RESTClient. May be somebody will find this question very simple to help me but I stumbled in it yesterday and can not solve this problem about two days. Everything works perfect if I use curl.exe utility:

set COOKIES=cookies.txt
set USER=jts
set PASSWORD=jts
set HOST="https://jazz.server.com:9443/qm"
curl -k -c %COOKIES% "%HOST%/authenticated/identity"
curl -k -L -b %COOKIES% -c %COOKIES% -d j_username=%USER% -d j_password=%PASSWORD% "%HOST%/authenticated/j_security_check"

You can see that I have a good result with JSESSIONID parameter returned with cookies:

# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_jazz.server.com   FALSE   /   TRUE    0   LtpaToken2  0VkNWt7dIquUiEJJ4XlPqEgsIKW/PJD2x4ckihZTCC6Iofo+KGtXYUuWhwk8wLnQZCxA0SP9/lgkWte/sH3/3k1HFFbM7UX07pFbh/MxVBcGtzY9Yr2YC6T3jZClxVDOU2R6fQk1SAu8/6Mia9LgrBnqsvauldoChU0ZFEDhI/ogHbyUKsOhM8gZNx8kJrkUCj0NPOci07UjKgILCorDZoiw5uYAIyC07ZBS6CY3juxkwgkYXwRCbyhpZY6dEeQg+CE97OwFhQCO7KesrflVF6xGRmEiz7f5DDG7oscqM72HJ9SF4zSMgKBko38l60ba
#HttpOnly_jazz.server.com   FALSE   /   TRUE    0   JSESSIONID  0000bzfBh88AbZ6yGgn-IVAccGA:34261533-f9f3-43a1-a58d-95e3dfca7322
#HttpOnly_jazz.server.com   FALSE   /qm/authenticated/  TRUE    0   X-com-ibm-team-foundation-auth-loop-avoidance   false

But if I use RESTClient, I do first GET request:

Method:     GET<br>
URI:        https://jazz.server.com:9443/qm/authenticated/identity

Returned headers are:

Status Code: 200 OK
Cache-Control: no-cache="set-cookie, set-cookie2"
Content-Encoding: gzip
Content-Language: en-US
Content-Length: 1028
Content-Type: text/html; charset=UTF-8
Date: Mon, 18 Sep 2017 17:33:06 GMT
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Set-Cookie: JazzFormAuth=Form; Path=/qm; Secure
X-Powered-By: Servlet/3.0
X-com-ibm-team-repository-web-auth-msg: authrequired

Next I do a second POST request:

Method:     POST<br>
URI:        https://jazz.server.com:9443/qm/authenticated/j_security_check?j_username=jts&j_password=jts

The headers returned are:

Status Code: 400 Bad Request
Connection: Close
Content-Language: en-US
Content-Length: 757
Content-Type: text/html;UTF-8
Date: Mon, 18 Sep 2017 18:35:02 GMT
X-Powered-By: Servlet/3.0

Can somebody tell me what the difference is here? Why doesn't it work? Thank you very much for any help in advance! I'm really at a standstill now!

1

There are 1 answers

0
SBI On

I've experienced the same problems that you have. Sadly, setting the cookie store is not enough, you have to manually extract the jsession value and send it as a cross-site request forgery header. I will post an extract of a powershell script that does exactly this, it should be understandable and portable to other scripting and programming environments. I've reduced the lines to the 3 essential steps:

# fetch required cookies with a "failed" attempt at reaching a location
# that requires auth
./curl.exe -v -k -L `
    --cookie $cookies `
    --cookie-jar $cookies `
    "${server}authenticated/identity"

# now that we have the cookies, we can send our login information with proper
# cookies and credentials 
./curl.exe -v -k -L `
    --cookie $cookies `
    --cookie-jar $cookies `
    --data j_username=$username `
    --data j_password=$password `
    "${server}j_security_check"

# get the cookie value that we need to pass as a special header
$pattern = "JSESSIONID\s+([^\s]+)"
$cookieValue = Select-String -Path $cookies -Pattern $pattern |
    %{ $_.matches } |
    %{ $_.groups[1].value } |
    Select-Object -Unique

# we now have the cookies and also the jsessionid that we need.
./curl.exe -v -k -L `
    --cookie $cookies `
    --cookie-jar $cookies `
    --header X-Jazz-CSRF-Prevent:$cookieValue `
    -- other stuff to complete the call.

Notice the second to last line, where the X-Jazz-CSRF-Prevent header is set to the JSESSION id. This is the crucial bit that gets lost when trying to imitate browser interaction from the usual command line environments.