Ruby RestClient to access Rational Team Concert (RTC) REST

六眼飞鱼酱① 提交于 2021-02-08 08:45:22

问题


I want to use the Ruby gem RestClient to access records from Rational Team Concert (RTC) over REST URLs. I have done this successfully with other servers. When I use the REST URL in Chrome directly, I can get a record. However, when I use my Ruby code, I get back some page that includes a line:

net.jazz.ajax._appPath = "/ccm0001001/auth/authrequired";

I've tried all sorts of ways to pass the credentials, but nothing seems to work. This is what I want to use:

response = RestClient::Request.new(
    :method => :get,
    :url => uri,
    :user => "username",
    :password => "password",
    :verify_ssl => OpenSSL::SSL::VERIFY_NONE
).execute

Anyone ever use Ruby (or Python?) to access RTC over REST URLs, or have any ideas what I'm doing wrong?

Thanks!


回答1:


Not sure you are still stuck here, but for anyone else this might help.

First Rational Team Concert(RTC) and the other Jazz based products default to Form based authentication by default, this can be changed by the Jazz Administrators to support the standard Basic authentication or more complex methods like certificate based authentication for common access cards and the like TN0013: Jazz Team Server Authentication Explained. It is easy to tell if you have Form or Basic authentication, when you try and login via the browser are you directed to a login servlet page or prompted for an operating system/browser dialog

Form Auth redirects to login page like this: enter image description here

Basic Auth prompts via browser: enter image description here

I'll show some examples using Python and the Requests module to simplify the code, here is the leading boiler plate that proceeds the below snippets.

import requests
# quiet warnings for self-signed certificates
requests.packages.urllib3.disable_warnings()

base_url = "https://jazzserver.demo.com/ccm"
auth_uri = "/authenticated/identity"

jazz_user = "user"
jazz_pass = "secretpassword"

session = requests.Session()
session.verify = False
session.allow_redirects = True
session.headers = {'accept':'application/xml'}

If your administrator has activated Basic auth, then the example you provided would be sufficient as the authentication needed would already be in your session and when you requested a secured resource the credentials will be provided and your request will succeed.

session.auth = (jazz_user, jazz_pass)

# Request a protected resource, auth creds are stored in session
response = session.get(base_url + auth_uri)

Since your snippet above is not working, I would assume you are using Form authentication. In this case we need to do the standard form auth handshake of request a protected resource, follow redirect to form, post credentials to form with provided session id, verify we are logged in, and either follow redirect or retry protected resource.

print "Request for authenticated resource"
response = session.get(base_url + auth_uri)

#print response.text
print response.headers

if 'x-com-ibm-team-repository-web-auth-msg' in response.headers and response.headers['x-com-ibm-team-repository-web-auth-msg'] == 'authrequired':
    print "Not currently authenticated"

    # Form response
    print "Sending login POST"
    login_response = session.post(base_url + '/j_security_check', data={ 'j_username': jazz_user, 'j_password': jazz_pass } )
    print login_response.headers

    if 'x-com-ibm-team-repository-web-auth-msg' in login_response.headers and login_response.headers['x-com-ibm-team-repository-web-auth-msg'] == 'authrequired':
        print "Failed to authenticate"
        print login_response.status_code
        print login_response.text
        raise Exception( "Failed to login: ", login_response.text )

    print "Getting authenticated resource again now that we should be logged in:"
    response = session.get( base_url + auth_uri )

print response.headers
print response.text

I have not accessed a certificate based authentication server or have one set so I don't have any experience using the API against that yet.

Posted a full example that should work for either Basic or Form auth as a GitHub gist

Gist - rtc_request_example.py

Should give you an output like this:

    (rtc_client)sgwilbur@gura:~/workspaces/rtc_helper$ ./test_ccm.py
    Request for authenticated resource
    {'x-com-ibm-team-repository-web-auth-msg': 'authrequired', 'content-length': '1985', 'set-cookie': 'JSESSIONID=CEF68A74B1A8005EB91A90BA42F3F86A; Path=/ccm/; Secure; HttpOnly, JazzFormAuth=Form; Path=/ccm; Secure', 'expires': 'Wed, 31 Dec 1969 18:00:00 CST', 'server': 'Apache-Coyote/1.1', 'cache-control': 'private', 'date': 'Thu, 15 Jan 2015 18:43:35 GMT', 'content-type': 'text/html;charset=UTF-8'}
    Not currently authenticated
    Sending login POST
    {'content-length': '55', 'set-cookie': 'JSESSIONID=1FE94776634391C83E47210113D1A4D4; Path=/ccm/; Secure; HttpOnly, JSESSIONIDSSO=D91E3A4E3376D567AF93DD031ED48E72; Path=/; Secure; HttpOnly, X-com-ibm-team-foundation-auth-loop-avoidance=false; Secure', 'expires': 'Wed, 31 Dec 1969 18:00:00 CST', 'server': 'Apache-Coyote/1.1', 'cache-control': 'private', 'date': 'Thu, 15 Jan 2015 18:43:36 GMT', 'content-type': 'text/json;charset=utf-8'}
    Getting authenticated resource again now that we should be logged in:
    {'content-length': '55', 'set-cookie': 'X-com-ibm-team-foundation-auth-loop-avoidance=false; Secure', 'expires': 'Wed, 31 Dec 1969 18:00:00 CST', 'server': 'Apache-Coyote/1.1', 'cache-control': 'private', 'date': 'Thu, 15 Jan 2015 18:43:36 GMT', 'content-type': 'text/json;charset=utf-8'}
    {
        "userId": "sgwilbur",
        "roles": [
            "JazzAdmins"]
    }

-Sean




回答2:


Almost 6 years later, I remember to post some code I got working... This is my shitty Ruby implementation.

#!/usr/bin/ruby

require 'HTTParty'
require 'Nokogiri'
require 'pp'

###########################################################################

class Jazz
include HTTParty

def self.jazzSetup(authuri,proxyaddr,proxyport,username,password)
    @authuri=authuri
    @proxyaddr=proxyaddr
    @proxyport=proxyport
    @username=username
    @password=password

    @httparty_options={:verify=>false}
    if(not @proxyaddr.nil?)then
        @httparty_options[:http_proxyaddr]=@proxyaddr
    end
    if(not @proxyport.nil?)then
        @httparty_options[:http_proxyport]=@proxyport
    end
end

def self.jazzGet(inputuri)

    $stderr.puts "\n" + inputuri
    $stderr.puts 'First attempt to get'
    response=get(inputuri,@httparty_options)
    @httparty_options[:headers]={'Cookie'=>response.headers['set-cookie']}
    $stderr.puts "CODE: #{response.code}"
    $stderr.puts "MESG: #{response.message}"

    if(response.headers['x-com-ibm-team-repository-web-auth-msg']=='authrequired')then

        $stderr.puts 'Attempt to authenticate'
        @httparty_options[:query]={'j_username'=>@username,'j_password'=>@password}
        response=post(@authuri,@httparty_options)
        @httparty_options[:headers]={'Cookie'=>response.headers['set-cookie']}
        @httparty_options.delete(:query)
        $stderr.puts "CODE: #{response.code}"
        $stderr.puts "MESG: #{response.message}"

        if(response.headers['x-com-ibm-team-repository-web-auth-msg']=='authfailed')then
            # this might be a decprecated condition, have only see code 401
            $stderr.puts 'Authentication FAILED! (authfailed)'
            exit
        elsif(response.code==401)then
            $stderr.puts 'Authentication FAILED! (401)'
            exit
        else
            $stderr.puts 'Authentication success!'
        end

        $stderr.puts 'Second attempt to get'
        response=get(inputuri,@httparty_options)
        @httparty_options[:headers]={'Cookie'=>response.headers['set-cookie']}
        $stderr.puts "CODE: #{response.code}"
        $stderr.puts "MESG: #{response.message}"
    end

    response
end

end

def getNext(doc)
    rel=doc.xpath('//ds:dataSource').attr('rel')
    if((not rel.nil?) and ("next"==rel.value))then
        doc.xpath('//ds:dataSource').attr('href').value
    else nil end
end

###########################################################################

Jazz.jazzSetup(
    'https://blah.clm.ibmcloud.com/rm/j_security_check',
    '111.111.111.111',80, # proxy settings
    # nil,nil,          # no proxy used
    ENV['j_username'],ENV['j_password']
)


来源:https://stackoverflow.com/questions/26252991/ruby-restclient-to-access-rational-team-concert-rtc-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!