cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1018
Views
0
Helpful
3
Replies

Admin API Sync User Directory not found

Keonip
Level 1
Level 1

I am using a PowerShell script to attempt to sync a user to a directory. I am getting back a

{"code": 40401, "message": "Resource not found", "message_detail": "Directory not found", "stat": "FAIL"}

Generally when I modify the script I’m getting an “code”: 40401, “message”: “Resource not found”

This makes me believe its an Auth issue still

I Am able to successfully get /auth/v2/check to work however

function New-DuoRequest(){
    param(
        [Parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
            $apiHost,
        
        [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
            [ValidateNotNull()]
            $apiEndpoint,
        
        [Parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
            $apiKey,
        
        [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
            [ValidateNotNull()]
            $apiSecret,
        
        [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
            [ValidateNotNull()]
            $requestMethod = 'GET',
        
        [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
            [ValidateNotNull()]
            [System.Collections.Hashtable]$requestParams
    )
    $date = (Get-Date).ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss -0000")
    $formattedParams = ($requestParams.Keys | Sort-Object | ForEach-Object {$_ + "=" + [uri]::EscapeDataString($requestParams.$_)}) -join "&"
    
    #DUO Params formatted and stored as bytes with StringAPIParams
    $requestToSign = (@(
        $Date.Trim(),
        $requestMethod.ToUpper().Trim(),
        $apiHost.ToLower().Trim(),
        $apiEndpoint.Trim(),
        $formattedParams
    ).trim() -join "`n").ToCharArray().ToByte([System.IFormatProvider]$UTF8)
 
    $hmacsha1 = [System.Security.Cryptography.HMACSHA1]::new($apiSecret.ToCharArray().ToByte([System.IFormatProvider]$UTF8))
    $hmacsha1.ComputeHash($requestToSign) | Out-Null
    $authSignature = [System.BitConverter]::ToString($hmacsha1.Hash).Replace("-", "").ToLower()

    $authHeader = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(('{0}:{1}' -f $apiKey, $authSignature)))

    $httpRequest = @{
        URI         = ('https://{0}{1}' -f $apiHost, $apiEndpoint)
        Headers     = @{
            "X-Duo-Date"    = $Date
            "Authorization" = "Basic $authHeader"
        }
        Body = $requestParams
        Method      = $requestMethod
        ContentType = 'application/x-www-form-urlencoded'
    }
    
    $httpRequest
}

# Calling the function

$values = @{
    
    ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■'
    apiEndpoint     = '/admin/v1/users/directorysync/DIRECOTRYKEY/syncuser'
    requestMethod   = 'POST'
    requestParams   = @{username="JDOE"}
    apiSecret       = 'SECRETKEY'
    apiKey          = 'IKEY'
}
$contructWebRequest = New-DuoRequest @values

# Send the request
$wr = Invoke-WebRequest @contructWebRequest
$wr
3 Replies 3

DuoKristina
Cisco Employee
Cisco Employee

for DIRECTORY NOT FOUND I’d suggest double-checking the directory_key value in your apiEndpoint. If it was an authentication issue the response would not tell you the directory you specified wasn’t found, it would return a 401 like “Invalid signature in request credentials”.

Duo, not DUO.

Keonip
Level 1
Level 1

I have 100% checked the directory key and even attempted multiple directories

I copied the PowerShell example you have here to my test Windows VM, replaced some of the $values info with those specific to my API host (the censored ■■■■ text), Admin API integration key and secret key, and my directory key and the user to sync, and it worked.

PS C:\users\kristina\documents> $values = @{
>>
>>     ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■'
>>     apiEndpoint     = '/admin/v1/users/directorysync/DZkey/syncuser'
>>     requestMethod   = 'POST'
>>     requestParams   = @{username="duoprem.testuser@domain"}
>>     apiSecret       = 'skey'
>>     apiKey          = 'ikey'
>> }
PS C:\users\kristina\documents> echo $values

Name                           Value
----                           -----
apiEndpoint                    /admin/v1/users/directorysync/DZkey/syncuser
requestParams                  {username}
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
requestMethod                  POST
apiSecret                      skey
apiKey                         ikey


PS C:\users\kristina\documents> $contructWebRequest = New-DuoRequest @values
PS C:\users\kristina\documents> $wr = Invoke-WebRequest @contructWebRequest
PS C:\users\kristina\documents> $wr


StatusCode        : 200
StatusDescription : OK
Content           : {"response": {"message": "User duoprem.testuser@domain synced successfully.", "user": {"alias1": null, "alias2": null,
                    "alias3": null, "alias4": null, "aliases": {}, "created": 158...
RawContent        : HTTP/1.1 200 OK
                    Connection: keep-alive
                    Pragma: no-cache
                    Strict-Transport-Security: max-age=31536000
                    Content-Security-Policy: default-src 'self'; frame-src 'self' ; img-src 'self'  ; connect-src 's...
Forms             : {}
Headers           : {[Connection, keep-alive], [Pragma, no-cache], [Strict-Transport-Security, max-age=31536000], [Content-Security-Policy, default-src 'self';
                    frame-src 'self' ; img-src 'self'  ; connect-src 'self']...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : System.__ComObject
RawContentLength  : 899
Duo, not DUO.
Quick Links