cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1006
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.
Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community:

Quick Links