5.6 KiB
Cisco Notes #+Author: Yann Esposito
Device Flow [2021-07-01 Thu]
Prior to the Flow
All devices must have a client_id/client_secret to be able to perform the
flow.
So for all FMC we must create a new OAuth2 Device Grant client.
Simply give the scopes and the grants
must be ["device-grant"]
.
That's it!
No redirect_uri
Work to be done once by the Team (FMC)
The JWT of the owner of the client (an FMC developer).
"eyJhbGciOiJS...."
POST https://visibility.int.iroh.site/iroh/oauth2-clients/clients
Accept: application/json
Content-Type: application/json
User-Agent: ob-http
Authorization: Bearer ${jwt}
{
"scopes": ["profile","inspect"],
"description": "Device Grant Demo Client",
"availability": "everyone",
"name": "Device Grant Demo",
"grants": ["device-grant"]
}
{
"scopes": [
"profile",
"inspect"
],
"description": "Device Grant Demo Client",
"approved?": true,
"redirects": [],
"availability": "everyone",
"password": "Hkd4ihtMG2Ivr0gm7UPVgED2iyWFjNLjaC403TN7z11VKB5VyU25xg",
"name": "Device Grant Demo",
"org-id": "63489cf9-561c-4958-a13d-6d84b7ef09d4",
"enabled?": true,
"grants": [
"device-grant"
],
"client-type": "confidential",
"id": "client-27d76a9a-3697-42f8-b492-2e21043afa92",
"approval-status": "approved",
"owner-id": "6ee52ee9-2e3a-4e1b-977d-961facb5fd84",
"created-at": "2021-07-01T09:49:49.372Z"
}
Side-note
IROH-Auth declares it supports the Device Grant Flow in the .well-known
.
Thus client applications developers could probably use tools that support
the Device Grant OAuth2 feature.
GET https://visibility.int.iroh.site/.well-known/oauth-authorization-server
Accept: application/json
Content-Type: application/json
User-Agent: ob-http
The Flow
The user should access a Device.
When the user want to link its SecureX account into the device.
The device makes a POST to SecureX to retrieve both a user_code
and
a device_code
.
POST https://visibility.int.iroh.site/iroh/oauth2/device_authorization
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: ob-http
client_id=client-27d76a9a-3697-42f8-b492-2e21043afa92&
client_secret=Hkd4ihtMG2Ivr0gm7UPVgED2iyWFjNLjaC403TN7z11VKB5VyU25xg
{
"device_code": "ifZh-vMeNMVkH3ypyQpBzNEE7EPRlPgeeDP7OoTuB_A1p5jffGqjrw",
"user_code": "2DCE2270",
"verification_uri": "https://visibility.int.iroh.site/iroh/oauth2/device",
"verification_uri_complete": "https://visibility.int.iroh.site/iroh/oauth2/device?user_code=2DCE2270",
"expires_in": 600,
"interval": 1
}
After that, the device should do two things:
- Display the user_code and ask the user to go to SecureX to grant the Device
- Continuously polling SecureX to get the user's access/refresh tokens
Polling before the user grant (or not) the client
POST https://visibility.int.iroh.site/iroh/oauth2/token
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: ob-http
client_id=client-27d76a9a-3697-42f8-b492-2e21043afa92&
client_secret=Hkd4ihtMG2Ivr0gm7UPVgED2iyWFjNLjaC403TN7z11VKB5VyU25xg&
grant_type=urn:ietf:params:oauth:grant-type:device_code&
device_code=ifZh-vMeNMVkH3ypyQpBzNEE7EPRlPgeeDP7OoTuB_A1p5jffGqjrw
{"client-id":"client-27d76a9a-3697-42f8-b492-2e21043afa92",
"trace_id": "f41a5c4b-2c6b-4130-89d7-1aa91542fc16",
"error_description":"Authorization pending",
"error_uri":"https://datatracker.ietf.org/doc/html/rfc8628#section-3.5",
"error":"authorization_pending"}
The HTTP code is 400;
Ask the user to grant the Device
- Go to the generic "Enter the code page" (
verification_uri
) - Send the user to a prefilled with the code "Grant the Client Page"
(
verification_uri_complete
).
Remarks:
- We could use a QRCode if the device is not reachable via a Browser.
- We should probably use a URL shortener for the
verification_uri
.
Polling for user answer/credentials
After the user granted the client:
POST https://visibility.int.iroh.site/iroh/oauth2/token
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: ob-http
client_id=client-27d76a9a-3697-42f8-b492-2e21043afa92&
client_secret=Hkd4ihtMG2Ivr0gm7UPVgED2iyWFjNLjaC403TN7z11VKB5VyU25xg&
grant_type=urn:ietf:params:oauth:grant-type:device_code&
device_code=ifZh-vMeNMVkH3ypyQpBzNEE7EPRlPgeeDP7OoTuB_A1p5jffGqjrw
{
"access_token": "eyJhbGciOi...",
"scope": "profile inspect",
"token_type": "bearer",
"expires_in": 600,
"refresh_token": "eyJhb...."
}
Remark: Any further attempt result in a 404:
POST https://visibility.int.iroh.site/iroh/oauth2/token
Accept: application/json
Content-Type: application/x-www-form-urlencoded
User-Agent: ob-http
client_id=client-27d76a9a-3697-42f8-b492-2e21043afa92&
client_secret=Hkd4ihtMG2Ivr0gm7UPVgED2iyWFjNLjaC403TN7z11VKB5VyU25xg&
grant_type=urn:ietf:params:oauth:grant-type:device_code&
device_code=ifZh-vMeNMVkH3ypyQpBzNEE7EPRlPgeeDP7OoTuB_A1p5jffGqjrw
{
"client-id": "client-27d76a9a-3697-42f8-b492-2e21043afa92",
"error_uri": "https://datatracker.ietf.org/doc/html/rfc8628#section-3.5",
"trace_id": "522a5c4b-2c6b-4130-89d7-1aa91542fc16",
"error": "invalid_device_code",
"error_description": "device code not found"
}