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

Commit 98933bf

Browse files
author
stas
committed
Support of certificate based authentication in RAFT for Restler #233
1 parent f2b624a commit 98933bf

File tree

4 files changed

+65
-26
lines changed

4 files changed

+65
-26
lines changed

docs/authentication.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ 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 certificate is supported by RESTler. It can be used by using **Cert** as
80+
authentication method and pass path to certificate as the value of **Cert** authentication method.
81+
Certificate must be X.509 certificate in PEM format. You can pass an authentication certificate using file shares.
82+
See `ReadOnlyFileShareMounts` section in [JobDefinition documentation](./schema/jobdefinition.md).
83+
84+
```
85+
"tasks": [
86+
{
87+
"toolName" : "RESTler",
88+
"authenticationMethod": {
89+
"Cert": "/path/to/cert"
90+
}
91+
},
92+
```
93+
7794

7895
## Agent-Utilities container
7996
Starting with v4 of RAFT - a deicated utilities docker container is deployed with every job run. This container is responsible

src/Agent/RESTlerAgent/AgentMain.fs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -260,22 +260,26 @@ 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+
Raft.RESTlerTypes.Engine.Cert {CertificatePath = authSecret}
270+
else
271+
let authConfig : Raft.RESTlerTypes.Engine.RefreshableTokenOptions =
272+
{
273+
RefreshInterval = Option.defaultValue (int <| TimeSpan.FromHours(1.0).TotalSeconds) runConfiguration.AuthenticationTokenRefreshIntervalSeconds
274+
RefreshExec = "python3"
275+
RefreshArgs =
276+
let url =
277+
System.Uri(authenicationUrl, sprintf "auth/%s/%s" authType authSecret)
278+
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
279+
}
280+
printfn "Refreshable token configuration : %A" authConfig
281+
Raft.RESTlerTypes.Engine.Token authConfig
282+
| None -> Raft.RESTlerTypes.Engine.NoAuth
279283

280284
/// The delay in seconds after invoking an API that creates a new resource
281285
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)