Ruby RestClient访问Rational Team Concert(RTC)REST

时间:2014-10-08 09:02:23

标签: ruby rest rest-client rtc rational-team-concert

我想使用Ruby gem RestClient通过REST URL访问Rational Team Concert(RTC)中的记录。我已经成功地与其他服务器一起完成了当我直接在Chrome中使用REST URL时,我可以获得记录。但是,当我使用我的Ruby代码时,我会回到一些包含一行的页面:

  

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

我已尝试过各种方式来传递凭据,但似乎没有任何效果。这就是我想要使用的:

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

任何人都使用Ruby(或Python?)通过REST URL访问RTC,或者有任何想法我做错了什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

不确定你是否仍然被困在这里,但对于其他任何人来说,这可能会有所帮助。

默认情况下,第一个Rational Team Concert(RTC)和其他基于Jazz的产品默认为基于表单的身份验证,这可以由Jazz管理员更改为支持标准基本身份验证或更复杂的方法,如基于证书的常见访问卡身份验证等TN0013: Jazz Team Server Authentication Explained。很容易判断您是否具有表单或基本身份验证,当您尝试通过浏览器登录时,您将被定向到登录servlet页面或提示您输入操作系统/浏览器对话框

表单身份验证重定向到登录页面,如下所示: enter image description here

基本身份验证通过浏览器提示: enter image description here

我将展示一些使用Python和Requests模块来简化代码的示例,这里是下面的代码片段的主要版本。

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'}

如果您的管理员已激活基本身份验证,那么您提供的示例就足够了,因为您的会话中已经存在所需的身份验证,当您请求安全资源时,将提供凭据并且您的请求将成功。

session.auth = (jazz_user, jazz_pass)

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

由于上面的代码段不起作用,我假设您使用的是表单身份验证。在这种情况下,我们需要执行请求受保护资源的标准表单auth握手,按照重定向到表单,使用提供的会话ID发布凭证以表明,验证我们已登录,并遵循重定向或重试受保护资源。

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

我没有访问过基于证书的身份验证服务器或拥有一套,因此我还没有任何使用该API的经验。

发布了一个完整的例子,应该作为GitHub要点使用Basic或Form auth

Gist - rtc_request_example.py

应该给你这样的输出:

    (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

答案 1 :(得分:1)

大约6年后,我记得发布了一些我正在工作的代码...这是我卑鄙的Ruby实现。

#!/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']
)