Pour certains scénarios, il peut être nécessaire d'obtenir un accès REST API dans un contexte utilisateur en utilisant le flux d'autorisation de l'appareil. Les étapes pour mettre cela en place ont été documentées en PowerShell, mais tout langage fera l'affaire. Voici comment cela fonctionne :
Interroger l'accès URI de configuration OpenID bien connu pour récupérer les points de terminaison du jeton du serveur et d'autorisation d'appareil :
try {
$wellKnownResponse = Invoke-RestMethod -Method Get -Uri $wellKnownEndpoint
$tokenEndpoint = $wellKnownResponse.token_endpoint
$deviceCodeEndpoint = $wellKnownResponse.device_authorization_endpoint
} catch {
Write-Error "Error obtaining server information"
exit
}
Envoyer une requête au point de terminaison d'autorisation de l'appareil pour un code appareil, un code utilisateur, une URL de vérification, et une URL de vérification complète, ainsi que des détails concernant la durée de validité des codes et la fréquence de vérification. Ensuite, soit ouvrir un navigateur sur l'URL de vérification complète, soit diriger l'utilisateur pour qu'il entre manuellement son code utilisateur et approuve la demande d'accès à l'appareil :
$body = "client_id=$clientId&scope=$([uri]::EscapeDataString($scope))"
try {
$deviceCodeResponse = Invoke-RestMethod -Method Post -Uri $deviceCodeEndpoint `
-ContentType "application/x-www-form-urlencoded" -Body $body
} catch {
Write-Error "Failed to obtain device code: $_"
exit
}
# Extract values from the response (field names may vary by provider)
$device_code = $deviceCodeResponse.device_code
$user_code = $deviceCodeResponse.user_code
$verification_uri = $deviceCodeResponse.verification_uri
$verification_uri_complete = $deviceCodeResponse.verification_uri_complete
$interval = 10 # in seconds
$expires_in = $deviceCodeResponse.expires_in # in seconds
# Provide a default interval if none was returned or if it's zero/null
if (-not $interval -or $interval -eq 0) {
$interval = 5
Write-Host "Interval not provided or invalid; defaulting to $interval seconds."
}
# Instead of instructing the user, open the browser to the verification_uri_complete
if ($verification_uri_complete) {
Write-Host "Opening browser for device authorization..."
Start-Process $verification_uri_complete
} else {
Write-Host "verification_uri_complete not provided. Please manually go to $verification_uri and enter the code: $user_code"
}
Démarrer une boucle qui envoie périodiquement une requête au point de terminaison du jeton avec le code appareil et l'ID client jusqu'à ce que le serveur retourne un jeton d'accès :
$startTime = Get-Date
$tokenResponse = $null
while (((Get-Date) - $startTime).TotalSeconds -lt $expires_in) {
Start-Sleep -Seconds $interval
try {# Build the POST body to exchange the device code for an access token
$tokenBody = "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=$clientId&device_code=$device_code"
$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType "application/x-www-form-urlencoded" -Body $tokenBody
if ($tokenResponse.access_token) {
Write-Host "Access token obtained:" $tokenResponse.access_token
break
}
}
catch {# Instead of reading the response content (which may be disposed), use the exception message.
$errorMessage = $_.Exception.Message
# Check if the exception message indicates that authorization is still pending.
if ($errorMessage -match "authorization_pending") {
Write-Host "Authorization pending..."
continue
}
else {
Write-Error "Error during token polling: $errorMessage"
break
}
}
}
if (-not $tokenResponse -or -not $tokenResponse.access_token) {
Write-Host "Failed to obtain an access token or authorization expired."
}
Lorsque nécessaire, utiliser le jeton de rafraîchissement obtenu lors de l'étape #1 pour demander un nouveau jeton via le point de terminaison du jeton, garantissant un accès continu à l'application :
$body = "grant_type=refresh_token&authorization=bearer $($tokenResponse.access_token)&refresh_token=$($tokenResponse.refresh_token)&client_id=dvls"
try {
$refreshResponse = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -ContentType "application/x-www-form-urlencoded" -Body $body
if ($refreshResponse.access_token) {
Write-Host "Access token obtained:" $tokenResponse.access_token
break
}
} catch {
Write-Error "Failed to obtain device code: $_"
exit
}
Voir la documentation d'Okta pour plus d'informations sur le flux d'autorisation de l'appareil.