Skip to content
This repository was archived by the owner on Feb 2, 2022. It is now read-only.

Commit 6fcfefc

Browse files
stishkinstas
andauthored
Support of certificate based authentication in RAFT for Restler #233 (#234)
Co-authored-by: stas <[email protected]>
1 parent f2b624a commit 6fcfefc

File tree

4 files changed

+73
-27
lines changed

4 files changed

+73
-27
lines changed

docs/authentication.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,30 @@ key vault is expected to be a string.
7474

7575
The string is passed to the container in an environment variable.
7676

77+
## Certificate (RESTler only at this time)
78+
79+
Authentication using a certificate is supported by RESTler.
80+
You have to pass the authentication certificate using file shares in RAFT.
81+
82+
Using **Cert** as the authentication method key, use the path to the certificate as the value.
83+
The certificate must be an X.509 certificate in PEM format.
84+
85+
See `ReadOnlyFileShareMounts` section in [JobDefinition documentation](./schema/jobdefinition.md)
86+
for details on how to mount file shares.
87+
88+
```
89+
"tasks": [
90+
{
91+
"toolName" : "RESTler",
92+
"authenticationMethod": {
93+
"Cert": "/path/to/cert"
94+
}
95+
},
96+
```
97+
7798

7899
## Agent-Utilities container
79-
Starting with v4 of RAFT - a deicated utilities docker container is deployed with every job run. This container is responsible
100+
Starting with v4 of RAFT - a dedicated utilities docker container is deployed with every job run. This container is responsible
80101
for performing authentication with a service under test and processing events from tools.
81102

82103
You do not need to do anything special to update agent utilites when running RAFT local, since agent utilities used directly from your CLI folder. To update agent utiliites when

src/Agent/RESTlerAgent/AgentMain.fs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -260,22 +260,29 @@ let createRESTlerEngineParameters
260260
match task.AuthenticationMethod with
261261
| Some c ->
262262
if c.IsEmpty then
263-
None
263+
Raft.RESTlerTypes.Engine.NoAuth
264264
else
265-
let authConfig : Raft.RESTlerTypes.Engine.RefreshableTokenOptions =
266-
{
267-
RefreshInterval = Option.defaultValue (int <| TimeSpan.FromHours(1.0).TotalSeconds) runConfiguration.AuthenticationTokenRefreshIntervalSeconds
268-
RefreshExec = "python3"
269-
RefreshArgs =
270-
let url =
271-
let auth = Seq.head c
272-
let authType, authSecretName = auth.Key, auth.Value
273-
System.Uri(authenicationUrl, sprintf "auth/%s/%s" authType authSecretName)
274-
sprintf """-c "import requests; import json; r=requests.get('%s'); assert r.ok, r.text; print(\"{u'user1':{}}\nAuthorization: \" + json.loads(r.text)['token'])" """ url.AbsoluteUri
275-
}
276-
printfn "Refreshable token configuration : %A" authConfig
277-
Some authConfig
278-
| None -> None
265+
let auth = Seq.head c
266+
let authType, authSecret = auth.Key, auth.Value
267+
268+
if authType.ToLower().Trim() = "cert" then
269+
if IO.File.Exists authSecret then
270+
Raft.RESTlerTypes.Engine.Cert {CertificatePath = authSecret}
271+
else
272+
failwithf "Failed to find authentication certificate: %s" authSecret
273+
else
274+
let authConfig : Raft.RESTlerTypes.Engine.RefreshableTokenOptions =
275+
{
276+
RefreshInterval = Option.defaultValue (int <| TimeSpan.FromHours(1.0).TotalSeconds) runConfiguration.AuthenticationTokenRefreshIntervalSeconds
277+
RefreshExec = "python3"
278+
RefreshArgs =
279+
let url =
280+
System.Uri(authenicationUrl, sprintf "auth/%s/%s" authType authSecret)
281+
sprintf """-c "import requests; import json; r=requests.get('%s'); assert r.ok, r.text; print(\"{u'user1':{}}\nAuthorization: \" + json.loads(r.text)['token'])" """ url.AbsoluteUri
282+
}
283+
printfn "Refreshable token configuration : %A" authConfig
284+
Raft.RESTlerTypes.Engine.Token authConfig
285+
| None -> Raft.RESTlerTypes.Engine.NoAuth
279286

280287
/// The delay in seconds after invoking an API that creates a new resource
281288
ProducerTimingDelay = Option.defaultValue 10 runConfiguration.ProducerTimingDelay

src/Agent/RESTlerAgent/RESTlerDriver.fs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@ module private RESTlerInternal =
341341
async {
342342
do!
343343
match parameters.RefreshableTokenOptions with
344-
| None -> async.Return()
345-
| Some t -> validateAuthentication workingDirectory t
344+
| Raft.RESTlerTypes.Engine.NoAuth | Raft.RESTlerTypes.Engine.Cert _ -> async.Return()
345+
| Raft.RESTlerTypes.Engine.Token t -> validateAuthentication workingDirectory t
346346

347347
let testParameters = getCommonParameters workingDirectory (Some testType) parameters
348348
do! runRestlerEngine restlerRootDirectory workingDirectory testParameters
@@ -353,8 +353,8 @@ module private RESTlerInternal =
353353
async {
354354
do!
355355
match parameters.RefreshableTokenOptions with
356-
| None -> async.Return()
357-
| Some t -> validateAuthentication workingDirectory t
356+
| Raft.RESTlerTypes.Engine.NoAuth | Raft.RESTlerTypes.Engine.Cert _ -> async.Return()
357+
| Raft.RESTlerTypes.Engine.Token t -> validateAuthentication workingDirectory t
358358

359359
let fuzzingParameters = getCommonParameters workingDirectory (Some fuzzType) parameters
360360
do! runRestlerEngine restlerRootDirectory workingDirectory fuzzingParameters
@@ -364,8 +364,8 @@ module private RESTlerInternal =
364364
async {
365365
do!
366366
match parameters.RefreshableTokenOptions with
367-
| None -> async.Return()
368-
| Some t -> validateAuthentication workingDirectory t
367+
| Raft.RESTlerTypes.Engine.NoAuth | Raft.RESTlerTypes.Engine.Cert _ -> async.Return()
368+
| Raft.RESTlerTypes.Engine.Token t -> validateAuthentication workingDirectory t
369369

370370
let replayParameters =
371371
(getCommonParameters workingDirectory None parameters)

src/Agent/RESTlerAgent/RESTlerTypes.fs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ module Engine =
2020
RefreshArgs : string
2121
}
2222

23+
type CertAuthentication =
24+
{
25+
//Path to your X.509 certificate in PEM format. Provide for Certificate Based Authentication
26+
CertificatePath: string
27+
}
28+
29+
30+
type Authentication =
31+
| NoAuth
32+
| Token of RefreshableTokenOptions
33+
| Cert of CertAuthentication
2334

2435
type EnginePerResourceSetting =
2536
{
@@ -55,7 +66,7 @@ module Engine =
5566
MaxDurationHours : float option
5667

5768
/// The authentication options, when tokens are required
58-
RefreshableTokenOptions : RefreshableTokenOptions option
69+
RefreshableTokenOptions : Authentication
5970

6071
/// The delay in seconds after invoking an API that creates a new resource
6172
ProducerTimingDelay : int
@@ -161,6 +172,8 @@ module Engine =
161172
//in hours
162173
time_budget : float option
163174

175+
client_certificate_path: string option
176+
164177
token_refresh_cmd : string option
165178

166179
//seconds
@@ -229,6 +242,8 @@ module Engine =
229242
//seconds
230243
token_refresh_interval = None
231244

245+
client_certificate_path = None
246+
232247
//if set - poll for resource to be created before
233248
//proceeding
234249
wait_for_async_resource_creation = true
@@ -239,11 +254,13 @@ module Engine =
239254
}
240255

241256
static member FromEngineParameters (fuzzingMode: string option) (p : EngineParameters) =
242-
let tokenRefreshInterval, tokenRefreshCommand =
257+
let tokenRefreshInterval, tokenRefreshCommand, authCertificatePath =
243258
match p.RefreshableTokenOptions with
244-
| None -> None, None
245-
| Some options ->
246-
(Some options.RefreshInterval), (Some (sprintf "%s %s" options.RefreshExec options.RefreshArgs))
259+
| NoAuth -> None, None, None
260+
| Token options ->
261+
(Some options.RefreshInterval), (Some (sprintf "%s %s" options.RefreshExec options.RefreshArgs)), None
262+
| Cert options ->
263+
None, None, (Some options.CertificatePath)
247264
{
248265
Settings.Default with
249266
host = p.Host
@@ -255,6 +272,7 @@ module Engine =
255272
no_ssl = not p.UseSsl
256273
no_tokens_in_logs = not p.ShowAuthToken
257274
fuzzing_mode = fuzzingMode
275+
client_certificate_path = authCertificatePath
258276
token_refresh_cmd = tokenRefreshCommand
259277
token_refresh_interval = tokenRefreshInterval
260278
max_request_execution_time = Option.defaultValue Settings.Default.max_request_execution_time p.MaxRequestExecutionTime

0 commit comments

Comments
 (0)