Skip to content
danmacpherson edited this page Feb 7, 2013 · 5 revisions

OAuth

The various components of Aeolus use two-legged OAuth to secure their REST APIs. Two-legged OAuth is considerably different from standard OAuth, in that it just consists of a shared secret. Instead of a username and password, we have a consumer key and a consumer secret. The request is signed using this information, as well as a timestamp. There is also a short presentation available.

Developers: If you are running from a local git checkout, you may want to copy /etc/aeolus-conductor/oauth.json to your local checkout’s src/config/ to capture all of the OAuth setup that was done. aeolus-configure will update the production /etc/aeolus-conductor/oauth.json file, but it doesn’t modify any local checkouts. Otherwise, you’ll need to manually update oauth.json to match.

Where OAuth is used

  • Conductor uses the aeolus-image-rubygem library to speak OAuth (as a client) to the following components:
    • Image Warehouse
    • Image Factory
  • Image Factory uses a Python library to secure its REST API, and to speak to Image Warehouse
  • Image Warehouse presents a REST API secured with liboauth

Where OAuth is NOT used

  • Conductor itself is secured with HTTP Basic Auth, not OAuth
    • The aeolus-image CLI tool thus uses basic auth talking to Conductor
  • deltacloud uses HTTP Basic Auth, not OAuth

Configuration

aeolus-configure will generate new keys for multiple components:

  • Image Factory has two sets of keys placed in /etc/imagefactory/imagefactory.conf
    • warehouse_key and warehouse_secret are used by Factory to speak to Warehouse directly
    • The clients section is a key/value pair (where the value is the consumer secret) used to authenticate to Factory’s REST API
    • Conductor has keys for both of the above placed in its config/oauth.json configuration file, which is /etc/aeolus-conductor/oauth.json in production.

Finding the Keys

Although aeolus-configure should set all of this up (see above), there are times when you want to find the keys, either for debugging or in a manual setup.

  • Conductor has all the OAuth configuration it uses (as a /client/ only) in config/oauth.json. aeolus-configure writes this for the production /etc/aeolus-conductor/oauth.json.
  • For Image Factory, the keys are stored in /etc/imagefactory/imagefactory.conf.

Also be certain that Conductor, iwhd, and Factory got restarted after running aeolus-configure to make sure they actually picked up those settings!

Manually Querying OAuth components

Because tools like curl don’t support two-legged OAuth, you’ll need some specialized tools to interrogate OAuth-speaking components.

With irb

As long as you have irb and the “oauth” gem installed, you can use Ruby to query generic two-legged OAuth services. Here is an example for querying iwhd; substitute your own consumer_key and consumer_secret values from above, of course.

$ irb
>> require 'oauth'
=> true

>> consumer_key = "Xd8258ec3-362a-4a45-9176-9c089f70487d"
=> "Xd8258ec3-362a-4a45-9176-9c089f70487d"
>> consumer_secret = "0eeeaf83-ceeb-48e5-8490-d1b46b3b034b"
=> "0eeeaf83-ceeb-48e5-8490-d1b46b3b034b"

>> consumer = OAuth::Consumer.new(
?>   consumer_key,
?>   consumer_secret,
?>   :site => 'http://localhost:9090'
>> )
=> #<OAuth::Consumer:0x7fa3a9e3b918 @secret="0eeeaf83-ceeb-48e5-8490-d1b46b3b034b", @key="Xd8258ec3-362a-4a45-9176-9c089f70487d", @options={:authorize_path=>"/oauth/authorize", :site=>"http://localhost:9090", :oauth_version=>"1.0", :access_token_path=>"/oauth/access_token", :signature_method=>"HMAC-SHA1", :scheme=>:header, :proxy=>nil, :http_method=>:post, :request_token_path=>"/oauth/request_token"}

>> token = OAuth::AccessToken.new(consumer)
=> #<OAuth::AccessToken:0x7fa3a9dc0d58 @token="", @secret="", @params={}, @consumer=#<OAuth::Consumer:0x7fa3a9e3b918 @secret="0eeeaf83-ceeb-48e5-8490-d1b46b3b034b", @key="Xd8258ec3-362a-4a45-9176-9c089f70487d", @options={:authorize_path=>"/oauth/authorize", :site=>"http://localhost:9090", :oauth_version=>"1.0", :access_token_path=>"/oauth/access_token", :signature_method=>"HMAC-SHA1", :scheme=>:header, :proxy=>nil, :http_method=>:post, :request_token_path=>"/oauth/request_token"}

>> images = token.get('/images')
=> #<Net::HTTPOK 200 OK readbody=true>
>> images.body
=> "<objects>\n\t<object>\n\t\t<bucket>images</bucket>\n\t\t<key>eaa2ef24-68ac-4b37-b48b-735e7d2374d6</key>\n\t</object>\n\t<object>\n\t\t<bucket>images</bucket>\n\t\t<key>927bf032-8908-4023-bd14-d98f05dbd9f5</key>\n\t</object>\n\t<object>\n\t\t<bucket>images</bucket>\n\t\t<key>0dd0494c-dff8-4662-a2c5-49a7c671c328</key>\n\t</object>\n\t<object>\n\t\t<bucket>images</bucket>\n\t\t<key>ff3c1ed9-b4f4-4743-88f3-276081883e67</key>\n\t</object>\n</objects>\n"
Clone this wiki locally