Project

General

Profile

API OAuth » History » Version 3

Marek Hulán, 11/16/2016 06:44 AM

1 1 Petr Chalupa
h1. API OAuth
2
3
There is two legged OAuth protocol added in API allowing request authentication.
4
5
Signed request with OAuth (using @oauth_consumer_key@ and @oauth_consumer_secret@) are trusted by Foreman. If request verification is successful a Foreman user is authenticated. Depending on @oauth_map_users@ option the incoming request is executed as admin or as mapped user. If @oauth_map_users@ is enabled users are mapped by @User#login@ passed in @X-FOREMAN-USER@ header.
6
7
h2. Setup
8
9 3 Marek Hulán
# go to http://foreman.url/settings?utf8=%E2%9C%93&search=+category++%3D++Auth
10 1 Petr Chalupa
# enable OAuth authetication @oauth_active@, set to @true@
11
# set @oauth_consumer_key@ and @oauth_consumer_secret@
12
# optionally set @oauth_map_users@ to @true@ to enable user mapping
13
14
h2. Troubleshooting
15
16
* if you have trouble enabling OAuth authentication watch Foreman log WARN messages.
17
* or debug OAuth authentication logic, see: source:lib/api/authorization.rb
18 2 Petr Chalupa
19
h2. Security
20 1 Petr Chalupa
21 3 Marek Hulán
OAuth does not signs whole request (body and @FOREMAN-USER@ are not signed), Api should be exposed over HTTPS.
22
23
h2. Examples
24
25
To list architectures using curl
26
27
<pre>
28
curl -X GET 'https://foreman.example.tst/api/v2/architectures' -H 'Content-Type: application/json' -H 'ForemanApiVersion: 2' \
29
-H 'Authorization: OAuth oauth_version="1.0",oauth_consumer_key="a",oauth_signature_method="hmac-sha1",oauth_signature="PlLTrHk5+aMgJACtww61dqakAWg=' -H 'FOREMAN-USER: ares'
30
</pre>
31
32
@oauth_consumer_key@ is set to a, @oauth_map_users@ is enabled so we set FOREMAN-USER header. The signature is normally computed by oauth client library, in this case I got it from server, it uses following algorithm
33
34
<pre><code class="ruby">
35
base = [method, normalized_uri, normalized_parameters]
36
base = base.map { |v| escape(v) }.join("&")
37
Base64.encode64(base).chomp.gsub(/\n/,'')
38
</code></pre>
39
40
as you can see, only method, URI and parameters are signed and verified on server side. Note that in real world usage, you should also include oauth_timestamp and oauth_nonce headers to prevent replay attacks.