Support of certificate based authentication in RAFT for Restler #233 (#234)

Co-authored-by: stas <statis@microsoft.com>
This commit is contained in:
Stas 2021-08-23 14:19:54 -07:00 коммит произвёл GitHub
Родитель f2b624ab83
Коммит 6fcfefc832
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 73 добавлений и 27 удалений

Просмотреть файл

@ -74,9 +74,30 @@ key vault is expected to be a string.
The string is passed to the container in an environment variable.
## Certificate (RESTler only at this time)
Authentication using a certificate is supported by RESTler.
You have to pass the authentication certificate using file shares in RAFT.
Using **Cert** as the authentication method key, use the path to the certificate as the value.
The certificate must be an X.509 certificate in PEM format.
See `ReadOnlyFileShareMounts` section in [JobDefinition documentation](./schema/jobdefinition.md)
for details on how to mount file shares.
```
"tasks": [
{
"toolName" : "RESTler",
"authenticationMethod": {
"Cert": "/path/to/cert"
}
},
```
## Agent-Utilities container
Starting with v4 of RAFT - a deicated utilities docker container is deployed with every job run. This container is responsible
Starting with v4 of RAFT - a dedicated utilities docker container is deployed with every job run. This container is responsible
for performing authentication with a service under test and processing events from tools.
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

Просмотреть файл

@ -260,22 +260,29 @@ let createRESTlerEngineParameters
match task.AuthenticationMethod with
| Some c ->
if c.IsEmpty then
None
Raft.RESTlerTypes.Engine.NoAuth
else
let authConfig : Raft.RESTlerTypes.Engine.RefreshableTokenOptions =
{
RefreshInterval = Option.defaultValue (int <| TimeSpan.FromHours(1.0).TotalSeconds) runConfiguration.AuthenticationTokenRefreshIntervalSeconds
RefreshExec = "python3"
RefreshArgs =
let url =
let auth = Seq.head c
let authType, authSecretName = auth.Key, auth.Value
System.Uri(authenicationUrl, sprintf "auth/%s/%s" authType authSecretName)
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
}
printfn "Refreshable token configuration : %A" authConfig
Some authConfig
| None -> None
let auth = Seq.head c
let authType, authSecret = auth.Key, auth.Value
if authType.ToLower().Trim() = "cert" then
if IO.File.Exists authSecret then
Raft.RESTlerTypes.Engine.Cert {CertificatePath = authSecret}
else
failwithf "Failed to find authentication certificate: %s" authSecret
else
let authConfig : Raft.RESTlerTypes.Engine.RefreshableTokenOptions =
{
RefreshInterval = Option.defaultValue (int <| TimeSpan.FromHours(1.0).TotalSeconds) runConfiguration.AuthenticationTokenRefreshIntervalSeconds
RefreshExec = "python3"
RefreshArgs =
let url =
System.Uri(authenicationUrl, sprintf "auth/%s/%s" authType authSecret)
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
}
printfn "Refreshable token configuration : %A" authConfig
Raft.RESTlerTypes.Engine.Token authConfig
| None -> Raft.RESTlerTypes.Engine.NoAuth
/// The delay in seconds after invoking an API that creates a new resource
ProducerTimingDelay = Option.defaultValue 10 runConfiguration.ProducerTimingDelay

Просмотреть файл

@ -341,8 +341,8 @@ module private RESTlerInternal =
async {
do!
match parameters.RefreshableTokenOptions with
| None -> async.Return()
| Some t -> validateAuthentication workingDirectory t
| Raft.RESTlerTypes.Engine.NoAuth | Raft.RESTlerTypes.Engine.Cert _ -> async.Return()
| Raft.RESTlerTypes.Engine.Token t -> validateAuthentication workingDirectory t
let testParameters = getCommonParameters workingDirectory (Some testType) parameters
do! runRestlerEngine restlerRootDirectory workingDirectory testParameters
@ -353,8 +353,8 @@ module private RESTlerInternal =
async {
do!
match parameters.RefreshableTokenOptions with
| None -> async.Return()
| Some t -> validateAuthentication workingDirectory t
| Raft.RESTlerTypes.Engine.NoAuth | Raft.RESTlerTypes.Engine.Cert _ -> async.Return()
| Raft.RESTlerTypes.Engine.Token t -> validateAuthentication workingDirectory t
let fuzzingParameters = getCommonParameters workingDirectory (Some fuzzType) parameters
do! runRestlerEngine restlerRootDirectory workingDirectory fuzzingParameters
@ -364,8 +364,8 @@ module private RESTlerInternal =
async {
do!
match parameters.RefreshableTokenOptions with
| None -> async.Return()
| Some t -> validateAuthentication workingDirectory t
| Raft.RESTlerTypes.Engine.NoAuth | Raft.RESTlerTypes.Engine.Cert _ -> async.Return()
| Raft.RESTlerTypes.Engine.Token t -> validateAuthentication workingDirectory t
let replayParameters =
(getCommonParameters workingDirectory None parameters)

Просмотреть файл

@ -20,6 +20,17 @@ module Engine =
RefreshArgs : string
}
type CertAuthentication =
{
//Path to your X.509 certificate in PEM format. Provide for Certificate Based Authentication
CertificatePath: string
}
type Authentication =
| NoAuth
| Token of RefreshableTokenOptions
| Cert of CertAuthentication
type EnginePerResourceSetting =
{
@ -55,7 +66,7 @@ module Engine =
MaxDurationHours : float option
/// The authentication options, when tokens are required
RefreshableTokenOptions : RefreshableTokenOptions option
RefreshableTokenOptions : Authentication
/// The delay in seconds after invoking an API that creates a new resource
ProducerTimingDelay : int
@ -161,6 +172,8 @@ module Engine =
//in hours
time_budget : float option
client_certificate_path: string option
token_refresh_cmd : string option
//seconds
@ -229,6 +242,8 @@ module Engine =
//seconds
token_refresh_interval = None
client_certificate_path = None
//if set - poll for resource to be created before
//proceeding
wait_for_async_resource_creation = true
@ -239,11 +254,13 @@ module Engine =
}
static member FromEngineParameters (fuzzingMode: string option) (p : EngineParameters) =
let tokenRefreshInterval, tokenRefreshCommand =
let tokenRefreshInterval, tokenRefreshCommand, authCertificatePath =
match p.RefreshableTokenOptions with
| None -> None, None
| Some options ->
(Some options.RefreshInterval), (Some (sprintf "%s %s" options.RefreshExec options.RefreshArgs))
| NoAuth -> None, None, None
| Token options ->
(Some options.RefreshInterval), (Some (sprintf "%s %s" options.RefreshExec options.RefreshArgs)), None
| Cert options ->
None, None, (Some options.CertificatePath)
{
Settings.Default with
host = p.Host
@ -255,6 +272,7 @@ module Engine =
no_ssl = not p.UseSsl
no_tokens_in_logs = not p.ShowAuthToken
fuzzing_mode = fuzzingMode
client_certificate_path = authCertificatePath
token_refresh_cmd = tokenRefreshCommand
token_refresh_interval = tokenRefreshInterval
max_request_execution_time = Option.defaultValue Settings.Default.max_request_execution_time p.MaxRequestExecutionTime