Configure brute force protection

REST API is equipped with a brute force protection mechanism. By default, after 3 failed authentication attempts from the same IP address, the API will add a response delay which will progressively increase if the brute force attack continues. In addition, when an attempt to create an authentication session with the API fails, the responses will include only a generic error message, without any details about why the attempt has failed. You can configure these settings or disable brute force protection entirely.

Out of the box, only Adaxes service administrators have the rights to configure REST API. Other users can be granted such rights using a security role with the Write all properties permission assigned over Configuration objects.

Change settings

It's possible to configure delayed responses and generic error messages while brute force protection is disabled, but the new settings will not take effect until it is enabled.

 Enable/disable brute force protection

To enable/disable brute force protection, execute the following script and restart IIS on the computer where REST API component is installed.

In the script:

  • $serviceHost – the host name of the computer where the Adaxes service is installed.
  • $enableBruteForceProtection – set to $true to enable brute force protection or set to $false to disable it.
Adaxes 2023 and newer
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost"
$enableBruteForceProtection = $true

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential


# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

# Enable/disable brute force protection
$config = $restApi.ToJson("{elements: ['BruteForceProtection']}") | ConvertFrom-Json
$config.bruteForceProtection.enabled = $enableBruteForceProtection
$restApi.FromJson("{elements: ['BruteForceProtection']}", ($config | ConvertTo-Json -Depth 10))
Adaxes 2021.1
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost" 
$enableBruteForceProtection = $true 

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

# Enable/disable brute force protection.
$bruteForceSettings = $restApi.SignInBruteForceProtectionSettings
$bruteForceSettings.Enabled = $enableBruteForceProtection
$restApi.SignInBruteForceProtectionSettings = $bruteForceSettings
$restApi.SetInfo() 

After executing the script, restart IIS on the computer where REST API component is installed.

 Delayed responses

To change how many authentication attempts can be made before responses are delayed, execute the following script and restart IIS on the computer where REST API component is installed.

In the script:

  • $serviceHost – the host name of the computer where the Adaxes service is installed.
  • $maxFailedAttempts – the number of failed authentication attempts after which the response delay will kick in. Set to $null to disable delayed responses.
Adaxes 2023 and newer
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost"
$maxFailedAttempts = 3

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

# Enable/disable delayed responses.
$config = $restApi.ToJson("{elements: ['BruteForceProtection']}") | ConvertFrom-Json

if ($null -ne $maxFailedAttempts)
{
    $config.bruteForceProtection.delayResponseEnabled = $true
    $config.bruteForceProtection.delayResponseAttemptsCount = $maxFailedAttempts
}
else
{
    $config.bruteForceProtection.delayResponseEnabled = $false
}

if (-not $config.bruteForceProtection.enabled)
{
    Write-Warning "Settings will be saved but will not take effect. `
        Brute force protection is disabled."
}

# Save settings.
$restApi.FromJson("{elements: ['BruteForceProtection']}", ($config | ConvertTo-Json -Depth 10))
Adaxes 2021.1
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost" 
$maxFailedAttempts = 3 

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

# Enable/disable delayed responses.
$bruteForceSettings = $restApi.SignInBruteForceProtectionSettings
if ($null -ne $maxFailedAttempts)
{
    $bruteForceSettings.DelayResponseEnabled = $true
    $bruteForceSettings.DelayResponseAttemptsCount = $maxFailedAttempts
}
else
{
    $bruteForceSettings.DelayResponseEnabled = $false
}
if (-not $bruteForceSettings.Enabled)
{
    Write-Warning "Settings will be saved but will not take effect. `
        Brute force protection is disabled."
}

# Save settings.
$restApi.SignInBruteForceProtectionSettings = $bruteForceSettings
$restApi.SetInfo() 

After executing the script, restart IIS on the computer where REST API component is installed.

 Generic error messages

To configure whether generic or detailed authentication error messages are displayed, execute the following script and restart IIS on the computer where REST API component is installed.

In the script:

  • $serviceHost – the host name of the computer where the Adaxes service is installed.
  • $genericMessages – set to $true to show generic error messages, and set to $false to show detailed messages.
Adaxes 2023 and newer
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost"
$genericMessages = $true

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

# Enable/disable detailed error messages.
$config = $restApi.ToJson("{elements: ['BruteForceProtection']}") | ConvertFrom-Json
$config.bruteForceProtection.showGenericErrorMessageEnabled = $genericMessages
if (-not $config.bruteForceProtection.enabled)
{
    Write-Warning "Settings will be saved but will not take effect. `
        Brute force protection is disabled."
}

# Save settings.
$restApi.FromJson("{elements: ['BruteForceProtection']}", ($config | ConvertTo-Json -Depth 100))
Adaxes 2021.1
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost" 
$genericMessages = $true 

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

# Enable/disable detailed error messages.
$bruteForceSettings = $restApi.SignInBruteForceProtectionSettings
$bruteForceSettings.ShowGenericErrorMessageEnabled = $genericMessages
if (-not $bruteForceSettings.Enabled)
{
    Write-Warning "Settings will be saved but will not take effect. `
        Brute force protection is disabled."
}

# Save settings.
$restApi.SignInBruteForceProtectionSettings = $bruteForceSettings
$restApi.SetInfo() 

After executing the script, restart IIS on the computer where REST API component is installed.

View current settings

Execute the following script. In the script:

  • $serviceHost – the host name of the computer where the Adaxes service is installed.
Adaxes 2023 and newer
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost"

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi

$config = $restApi.ToJson("{elements: ['BruteForceProtection']}") | ConvertFrom-Json

# Brute force protection
if (-not $config.bruteForceProtection.enabled)
{
    Write-Host "Brute force protection is disabled."
    return
}

# Generic messages
if ($config.bruteForceProtection.showGenericErrorMessageEnabled) 
{ 
    Write-Host "Generic error messages: Enabled" 
}
else 
{ 
    Write-Host "Generic error messages: Disabled" 
}

# Response delay
if ($config.bruteForceProtection.delayResponseEnabled)
{
    Write-Host "Response delay after:" `
        $config.bruteForceProtection.delayResponseAttemptsCount "attempts"    
}
else
{ 
    Write-Host "Response delay: Disabled." 
}
Adaxes 2021.1
[Reflection.Assembly]::LoadWithPartialName("Softerra.Adaxes.Adsi")

$serviceHost = "localhost" 

# Connect to the Adaxes service.
$ns = New-Object "Softerra.Adaxes.Adsi.AdmNamespace"
$service = $ns.GetServiceDirectly($serviceHost)

# Prompt for credentials.
$credential = Get-Credential

# Bind to the REST API configuration container.
$containerPath = $service.Backend.GetConfigurationContainerPath("ClientAppsContainer")
$container = $service.OpenObject($containerPath, $credential.UserName, `
    $credential.GetNetworkCredential().Password, 0)
$restApi = $container.RestApi
$bruteForceSettings = $restApi.SignInBruteForceProtectionSettings

# Brute force protection
if (-not $bruteForceSettings.Enabled)
{
    Write-Host "Brute force protection is disabled."
    return
}

# Generic messages
if ($bruteForceSettings.ShowGenericErrorMessageEnabled) 
{ 
    Write-Host "Generic error messages: Enabled" 
}
else 
{ 
    Write-Host "Generic error messages: Disabled" 
}

# Response delay
if ($bruteForceSettings.DelayResponseEnabled)
{
    Write-Host "Response delay after:" `
        $bruteForceSettings.DelayResponseAttemptsCount "attempts"    
}
else
{ 
    Write-Host "Response delay: Disabled." 
}