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. |