207 lines
5.6 KiB
Org Mode
207 lines
5.6 KiB
Org Mode
|
# Created 2021-07-01 Thu 17:52
|
||
|
#+TITLE: Cisco Notes #+Author: Yann Esposito
|
||
|
#+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).
|
||
|
|
||
|
#+name: intmasterjwt
|
||
|
#+begin_src elisp
|
||
|
"eyJhbGciOiJS...."
|
||
|
#+end_src
|
||
|
|
||
|
#+header: :var jwt=intmasterjwt
|
||
|
#+begin_src http
|
||
|
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"]
|
||
|
}
|
||
|
#+end_src
|
||
|
|
||
|
#+results:
|
||
|
#+begin_src http
|
||
|
{
|
||
|
"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"
|
||
|
}
|
||
|
#+end_src
|
||
|
|
||
|
|
||
|
*** 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.
|
||
|
|
||
|
#+begin_src http
|
||
|
GET https://visibility.int.iroh.site/.well-known/oauth-authorization-server
|
||
|
Accept: application/json
|
||
|
Content-Type: application/json
|
||
|
User-Agent: ob-http
|
||
|
#+end_src
|
||
|
|
||
|
** 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=**.
|
||
|
|
||
|
#+begin_src http
|
||
|
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
|
||
|
#+end_src
|
||
|
|
||
|
#+results:
|
||
|
#+begin_src http
|
||
|
{
|
||
|
"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
|
||
|
}
|
||
|
#+end_src
|
||
|
|
||
|
After that, the device should do two things:
|
||
|
|
||
|
1. Display the **user_code** and ask the user to go to SecureX to
|
||
|
grant the Device
|
||
|
2. Continuously polling SecureX to get the user's access/refresh tokens
|
||
|
|
||
|
|
||
|
*** Polling before the user grant (or not) the client
|
||
|
|
||
|
#+begin_src http
|
||
|
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
|
||
|
#+end_src
|
||
|
|
||
|
#+results:
|
||
|
#+begin_src http
|
||
|
{"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"}
|
||
|
#+end_src
|
||
|
|
||
|
The HTTP code is *400*;
|
||
|
|
||
|
*** Ask the user to grant the Device
|
||
|
|
||
|
1. Go to the generic "Enter the code page" (=verification_uri=)
|
||
|
2. 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:
|
||
|
|
||
|
#+begin_src http
|
||
|
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
|
||
|
#+end_src
|
||
|
|
||
|
#+results:
|
||
|
#+begin_src http
|
||
|
{
|
||
|
"access_token": "eyJhbGciOi...",
|
||
|
"scope": "profile inspect",
|
||
|
"token_type": "bearer",
|
||
|
"expires_in": 600,
|
||
|
"refresh_token": "eyJhb...."
|
||
|
}
|
||
|
#+end_src
|
||
|
|
||
|
**Remark**:
|
||
|
Any further attempt result in a 404:
|
||
|
|
||
|
|
||
|
#+begin_src http
|
||
|
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
|
||
|
#+end_src
|
||
|
|
||
|
#+results:
|
||
|
#+begin_src http
|
||
|
{
|
||
|
"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"
|
||
|
}
|
||
|
#+end_src
|