OpenID Connect
OpenID Connect is an identity layer on top of OAuth2. The differences between the two are:
The client must contain the scope
openid
.The response from the
/iroh/oauth2/token
will contain not only an access token and a refresh token but also anid_token
.The scopes in the access and refresh tokens will behave as if the field
allow-partial-user-scopes
of your client was true. The scopes will be the biggest intersection between:- the user scopes
- the client scopes
- the requested scopes
The OpenID specification provides more details about OpenID Connect using Authorization Code Grant Flow.
OpenID Connect provides the ability for a user to grant access to your web application and and it also sends user identity information (email, name, and so on) to your application.
With this workflow, the user will not need to copy or paste any credentials. They just need to click on a button to authorize your client.
An OpenID Connect workflow follows these steps:
Create a single client for your application. This should only be done once.
Generate a link on your web application. When the user clicks on it, they are redirected to IROH, and they can grant access to your application. The user returns to your website with a secret code and you will then retrieve both a refresh token that you should keep securely and an id token.
Note: This should be done only once per user.
With the refresh token, you can retrieve an access token without user interaction.
Note: This should be done only when you want to call the API and the access token has expired (every 10 min by default).
The access token can be used to call the IROH APIs on behalf of the user.
Note: This should be done for all API calls, so we highly recommended that you cache the access tokens and not to call the refresh token for each API call to IROH.
Create a Client
There are two ways to create a client:
Both ways will result in the same outcome. But, before creating the OpenID Connect client, read this section in its entirety to determine the correct client configuration settings.
Mandatory Configuration Settings
- During client creation, add the openid scope to your client. This will declare the client as an OpenID Connect compatible client.
- During client creation, you must set the field
grants
to["auth-code"]
in order to support Authorization Code Grant workflow. - If you want to be autonomous, you will need to have control of an HTTPS URL (generally something along
https://my.domain.tld/path/to/callback
). This is the URL you’ll use to set in the redirects value of the client.
Depending on the information you provide during client creation, the client will not be automatically approved. The client will be approved during creation if all the following conditions are met:
availability
is either equal to"org"
or"user"
,redirects
contain only a list of HTTPS URLs,client-type
isconfidential
,scopes
contain only unrestricted scopes (see https://visibility.amp.cisco.com/iroh/oauth2-clients/index.html#!/Scopes/get_iroh_oauth2_clients_scopes) to retrieve a list of unrestricted scopes),access-token-lifetime-in-sec
andrefresh-token-lifetime-in-sec
are not provided.
For more details about each field, refer to the section OAuth2 Client Model.
Optional Configuration Settings
Provide Access to All Users
If you need to open your web application to all users and not only to the members of your organization, you will need to create a client with the
availability
field equal toeveryone
. The client won’t be approved and you’ll need to reach out to a IROHadministrator to approve it.Redirect to Localhost Without HTTPS
For clients with availability set to everyone, every URI in the
redirects
array must behttps
. If you need to you use another scheme in your URI, then you will need to reach out an administrator to approve your client.Create a Public Client
If your application is a front-end only application, having a password does not make sense. For this specific case, it is recommended (by the RFC) to not use the Implicit grant. Instead, use an Authorization Code Grant client without any password. In this case you must set the
client-type
topublic
.This is also a specific need. You will need to request approval from a IROH administrator.
Change Access Token Lifetime
The current default lifetime of access token is 10 minutes. The current default lifetime for refresh token is unlimited.
If you want a longer lived access token or shorter lived refresh token, you simply need to set the fields
access-token-lifetime-in-sec
andrefresh-token-lifetime-in-sec
when creating your client. You will need to request a IROH administrator approve your client.Note: After a refresh-token lifetime, the refresh token will no longer work. After half of the lifetime, when getting a new access token, you will also get a newer refresh token with the same lifetime. It is then up to you, the client, to perform a new refresh token call during the second half or 1 hour before the expiration to get a new refresh token. After a new refresh-token is provided, the old one can be revoked anytime so you should cease using the old refresh token.
Without a valid refresh token you will be forced to reengage the user in an interactive authorization workflow.
For more details about each field, refer to the section OAuth2 Client Model.
Using the Cisco XDR UI
Before creating a client, make sure to read the Client Configurations in its entirety to determine the correct client configuration settings.
Note: When creating an OAuth Code Client, there is an auto-approve feature if all criteria is met. If some criteria is not met, the client is created but disabled until it has been approved by a user with an Administrator role.
For details on how to create an OAuth Code Client, see the topic in the Cisco XDR Help.
Using the API (via the Swagger UI Interface)
Before creating a client, make sure to read the Client Configurations in its entirety to determine the correct client configuration settings.
The Swagger UI provides raw access to the API to create a client. However, the only way to work with this API is by using a JWT with the oauth
scope.
Retrieve the list of your scopes. You will not be able to create a client with more scopes than you are allowed to access.
To get the list of scopes, use the whoami profile API:
https://visibility.amp.cisco.com/iroh/profile/#!/Profile/get_iroh_profile_whoami
If you are already logged in to https://visibility.amp.cisco.com/, you will not need to enter any information in the Authorization header inputs in Swagger. If not, click Authorize and provide authorization with one of the followin: IROH login, apiKey, or OAuth2 credentials.
To use the /iroh/profile/whoami
API:
Open the
whoami
API Swagger UI.Click Try it out.
Click Execute.
Under Server response, assuming you received a HTTP status code of 200, you will find the response from the API request. It is a JSON containing your user and org information including the list of your scopes.
Here is example response from the /iroh/profile/whoami
API:
{
"user": {
"scopes": [
"admin",
"casebook",
"cisco",
"collect",
"enrich",
"global-intel:read",
"inspect",
"integration",
"oauth",
"private-intel",
"profile",
"response",
"ui-settings"
"users"
],
"updated-at": "2019-04-30T13:54:21.641Z",
"user-email": "dev.null@cisco.com",
"org-id": "13375cf9-561c-4958-0000-6d84b7ef09d4",
"user-id": "idb-amp:13375ee9-2e3a-4e1b-977d-961facb5fd84",
"idp-mappings": [{
"idp": "idb-amp",
"user-identity-id": "13375ee9-2e3a-4e1b-977d-961facb5fd84",
"organization-id": "13375cf9-561c-4958-0000-6d84b7ef09d4"
}],
"enabled?": true,
"last-logged-at": [
"2019-04-30T13:54:21.843Z"
],
"created-at": "2019-04-30T13:54:21.622Z"
},
"org": {
"scim-status": "activated",
"name": "IROH Testing",
"enabled?": true,
"id": "13375cf9-561c-4958-0000-6d84b7ef09d4",
"created-at": "2019-04-30T13:54:21.634Z"
}
}
For a description of each field, refer to the User Model section on the Data Model page.
Now that you know which scopes you have access to, you can now create the client.
To create the OAuth2 client, use the clients API:
To use the /iroh/oauth2-clients/clients
API:
Open the
clients
API Swagger UI: https://visibility.amp.cisco.com/iroh/oauth2-clients/index.html#/OAuth2Client/post_iroh_oauth2_clients_clients.Click Try it out.
Edit the JSON under CreateClientParams with the configuration for the client. For a description of each field, refer to the section OAuth2 Client Model.
Click Execute.
Under Server response, assuming you received a HTTP status code of 200, you will find the response from the API request. For a description of each field in the response, refer to the section OAuth2 Client Model.
Use the Client
If you have not yet created a client that can be used for Authorization Code Grant, refer to Create a Client.
If you have successfully created the client and it is approved, you should have the following information:
client-id
client-password
redirect-uri
; one of the URL(s) you set in theredirects
array of the clientscopes
; the list of scope you’ll ask IROH users to grant to your application. If it is not empty, it must containopenid
.
You will also need to know the authorization and token URLs of IROH. You can get them at the metadata endpoint (c.f. OAuth2 Metadata).
Present the URL to the User
The first step is to present the user with the URL (return line here is for readability only):
https://visibility.amp.cisco.com/iroh/oauth2/authorization?
response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_REDIRECT_URL
&scope=LIST_OF_SCOPES_SPACE_SEPARATED
&state=A_DIFFICULT_TO_GUESS_RANDOM_STRING
The scope query parameter is optional. Without it, the scopes will match those of the client. Once the user clicks on the link, they will be redirected to IROH and asked to grant access to your web application. If the user accepts or refuses, the user will be redirected to the redirect uri with parameters that will contain further information.
Get the Refresh Token
Listen to your redirect_uri
and parse the query parameters. An example of the URL the user will be redirected to after granting your app the access would be:
YOUR_REDIRECT_URL?state=A_DIFFICULT_TO_GUESS_RANDOM_STRING&code=SOME_CODE
Then, you must verify that the value of the state
is the same one the user has clicked on. (In our example, the state must be A_DIFFICULT_TO_GUESS_RANDOM_STRING
).
Next, get the refresh token by using the /iroh/oauth2/token
API with the value of the code query parameter in the request parameters.
Here is an example API request to /iroh/oauth2/token
using a cURL command:
curl -X POST \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_PASSWORD" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&redirect_uri=YOUR_REDIRECT_URL&code=SOME_CODE" \
'https://visibility.amp.cisco.com/iroh/oauth2/token'
The -u
is to use Basic Auth, with client-id
as user and client-password
as password. In order to manually supply the correct header, don’t forget to base64 encode the client_id:client_password
string. The following two code examples are interchangeable:
curl -u "client_id:client_password" https://example.com
and
creds=$(echo -n client_id:client_password | base64)
curl -H "Authorization: Basic $creds" https://example.com
It is also important to set the content type to application/x-www-form-urlencoded
.
Note: The route does not support parameters sent via a JSON Content-Type (cf. RFC6749 section 4.1.3).
The server should then return a successful response (cf. RFC6749 section 4.1.4):
{
"access_token":"eyJhbG...",
"id_token":"eyJhbG...",
"token_type":"bearer",
"expires_in":600,
"refresh_token":"eJJyFFA..."
}
Important: The POST to the
/token
route exposes your client password, so it must be done server side and not inside the browser.
You should have both an access token and a refresh token. The access token will expire in 600 seconds. But the refresh token does not expire soon. Make sure to save the refresh token for your user. Each time you need a new access token, you will need the refresh token.
Make an API Request Using the Access Token
Now that you have retrieved the access token (which is a JWT), you can make an API request on behalf of the user. However, it will be restricted to the scope they granted your application.
Here is an example request using the access token:
ACCESS_TOKEN="eyJhbGciO..."
curl -X POST \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{"content":"cisco.com"}' \
'https://visibility.amp.cisco.com}/iroh/iroh-inspect/inspect'
To see an exhaustive list of APIs with links to their swagger UI interfaces and a list of scopes, see Authorization Access / Scopes.
Get a New Access Token
The access token will expire (default is 10 minutes). API access after token expiration will require user interaction. You will need to use the refresh token of the user to get a new access token.
The request to refresh a token uses the same API you used to get it the first time. But instead of using a grant_type
of authorization_code
, you will use a grant_type
equal to refresh_token
(cf. RFC6749 section 6).
Example request:
curl -X POST \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_PASSWORD" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token&refresh_token=REFRESH_TOKEN" \
'https://visibility.amp.cisco.com/iroh/oauth2/token'
The server should then return a successful response:
{
"access_token":"eyJhbG...",
"token_type":"bearer",
"expires_in":600
}
IMPORTANT: The response might also contain a new refresh token along with the new access token. In that case, you must revoke the old refresh token and use the new one instead. IROH might accept the old refresh token for a short period to prevent bugs in distributed environments.
Tutorial
This section provides complete example. The credentials used will not be functional, but you should be able to follow all the steps with your own credentials.
Clone Demo Project
Clone the demo project from: https://github.com/yogsototh/oauth2-client-demo
Serve it to your own domain, possibly in some directory. This tutorial assumes it will be: https://my.domain.tld/ctr-oauth/
If you cannot test directly from your domain and want to test on localhost check the Run Demo on localhost section for instructions.
Create the Client
Use the /iroh/oauth2-clients/clients
API to create the client.
Here is an example API request to /iroh/oauth2-clients/clients
using a cURL command:
ACCESS_TOKEN="eyJhbGciO..."
curl -X 'POST' \
\
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'User-Agent: ob-http' \
-H 'Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"scopes": [ "profile", "inspect", "openid" ],
"description": "Developer Doc OAuth2 Test Client",
"redirects": [ "https://my.domain.tld/ctr-oauth/callback.html" ],
"availability": "org",
"name": "OAuth2 Developer Doc Test",
"grants": [ "auth-code" ],
"client-type": "confidential"
}' \
'https://visibility.amp.cisco.com/iroh/oauth2-clients/clients'
The server should then return a successful response:
{
"scopes": [
"profile",
"inspect",
"openid"
],
"description": "Developer Doc OAuth2 Test Client",
"approved?": true,
"redirects": [
"https://my.domain.tld/ctr-oauth/callback.html"
],
"availability": "org",
"password": "CrXwg31_vnRHpjPXzgVzUFKHr6RO8GTL-iI8aDeUU3n48NtD7PFLhg",
"name": "OAuth2 Developer Doc Test",
"org-id": "f47a89bf-5d2e-4392-b770-000000000000",
"enabled?": true,
"grants": [
"auth-code"
],
"client-type": "confidential",
"id": "client-3bb1e787-381d-4f12-bf32-e1158f200ddc",
"approval-status": "approved",
"owner-id": "f0010924-e1bc-4b03-b600-000000000000",
"created-at": "2019-07-25T14:15:29.117Z"
}
For a description of each field in the response, refer to the section OAuth2 Client Model.
Configure the Demo
Edit the info.js
to look like:
var oauthURLPrefix="https://visibility.amp.cisco.com";
var oauthServerUrl=oauthURLPrefix + "/iroh/oauth2/authorize";
var oauthServerTokenUrl=oauthURLPrefix + "/iroh/oauth2/token";
var resourceProviderTestEndpoint=oauthURLPrefix + "/iroh/profile/whoami" ;
var response_type="code";
var client_id="client-3bb1e787-381d-4f12-bf32-e1158f200ddc";
var client_password = "CrXwg31_vnRHpjPXzgVzUFKHr6RO8GTL-iI8aDeUU3n48NtD7PFLhg";
var redirect_uri="https://my.domain.tld/ctr-oauth/callback.html";
var scopes=[ "profile", "inspect", "openid" ];
var scope=scopes.join(" ");
var state="whatever=";
Run the Demo
- Go to the URL where the demo project was served on your domain (or localhost). In this tutorial, it would be
https://my.domain.tld/ctr-oauth/index.html
. - Click on the link. You will be redirected to IROH
- Authorize the client.
- Now back at
https://my.domain.tld/ctr-oauth/callback.html
, you should inspect the request in your browser and play with the demo. - Retrieve the access token and refresh token using the value of the
code
query parameter. - Get another access token using the refresh token.
Details About Steps in the Demo
While the workflow necessitates user interaction through the browser, we will describe most requests in detail.
- Code in callback URL
The user interaction is only needed to authorize the client. They will then visit the URL https://my.domain.tld/ctr-oauth/callback.html
and pass the query parameters code
and state
.
Here is an example URL:
https://my.domain.tld/ctr-oauth/callback.html?
code=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE1NjQxMjk4NDcsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3VzZXJcL2lkIjoiZjAwMTA5MjQtZTFiYy00YjAzLWI2MDAtODljNmNmNTI3NTdjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vcmdcL2lkIjoiZjQ3YTg5YmYtNWQyZS00MzkyLWI3NzAtYWQ0ODIxYTgyYWNmIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwvZ3JhbnQiOiJhdXRoLWNvZGUiLCJqdGkiOiJmMjFiMDU5NS04YzhjLTRkZTktOGI4MS01NWVmZTIwMThlODMiLCJuYmYiOjE1NjQxMjkxODcsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25hbWUiOiJZYW5uIEVzcG9zaXRvIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2NsaWVudFwvaWQiOiJjbGllbnQtM2JiMWU3ODctMzgxZC00ZjEyLWJmMzItZTExNThmMjAwZGRjIiwiaWF0IjoxNTY0MTI5MjQ3LCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC9raW5kIjoiY29kZS10b2tlbiJ9.IL5xGEfcwnKpd2KNMyo2_kNtkEsfwTa6vYKJHR6uF3L3CGX7edat_eYXNmLACgamX3pdYfXo8JAHEOvdr7zl6-fLq0SHlFdxy4pbVQbr8gJt6TAZVWgNu8wxJfTzL6-V0oIv6mcYD2NWTXYoA8R19u6iFnOtoTwXVx58Dk2UXQuueHmq2CejpJspGgjChAHsebh1XKl-6uPo7debCQvrzPhB56lGShKT0NgEqT_ZML032iFqGIBHUe6WdlqO_i6ji1-QX3CPmA_rwep7n0h1RuDxWib9YCtwJFh0SO0AQX_bK-0000000000000000000000000000000000000000
&state=y5jaXNjby5jb21cL2lyb2hcL2lkZW
The code
represents an agreement from a IROH user to grant access to your application. Remember OAuth2 Authorization Code Grant is a contract between three entities: your application (the client), the user, and IROH. The code
query parameter is a JWT. Once decoded it contains:
{
"https://schemas.cisco.com/iroh/identity/claims/user/email":"dev.null@cisco.com",
"https://schemas.cisco.com/iroh/identity/claims/user/scopes":[
"integration",
"private-intel",
"admin",
"profile",
"inspect",
"sse",
"users",
"casebook",
"enrich",
"oauth",
"global-intel:read",
"collect",
"response",
"ui-settings"
],
"https://schemas.cisco.com/iroh/identity/claims/user/nick":"Yann Esposito",
"email":"dev.null@cisco.com",
"iss":"IROH Auth",
"https://schemas.cisco.com/iroh/identity/claims/scopes":[
"profile",
"inspect",
"openid"
],
"exp":1564129847,
"https://schemas.cisco.com/iroh/identity/claims/oauth/user/id":"f0010924-e1bc-4b03-b600-000000000000",
"https://schemas.cisco.com/iroh/identity/claims/org/id":"f47a89bf-5d2e-4392-b770-000000000000",
"https://schemas.cisco.com/iroh/identity/claims/oauth/grant":"auth-code",
"jti":"f21b0595-8c8c-4de9-8b81-55efe2018e83",
"nbf":1564129187,
"https://schemas.cisco.com/iroh/identity/claims/oauth/scopes":[
"profile",
"inspect"
],
"https://schemas.cisco.com/iroh/identity/claims/user/name":"Yann Esposito",
"https://schemas.cisco.com/iroh/identity/claims/user/id":"f0010924-e1bc-4b03-b600-000000000000",
"https://schemas.cisco.com/iroh/identity/claims/oauth/client/id":"client-3bb1e787-381d-4f12-bf32-000000000000",
"iat":1564129247,
"https://schemas.cisco.com/iroh/identity/claims/oauth/kind":"code-token"
}
The JWT claims are detailed in the Call the API / JWT section. Note that the JWT contains three different claims related to scopes: the user scopes, the scope the user agreed to grant and the the scopes the client asked for.
Another field to note is the oauth/kind
that contains code-token
. This JWT can only be used as a temporary code during the OAuth2 workflow.
Also notice the expiration date (exp
) is just 10 minutes after the creation date (iat
).
IMPORTANT: Your client must check that the
state
parameter is the same as thestate
parameter in the link the user clicked on. Each time you present a link to grant your application to a user, you should generate a new strong random string.
- Get the access and refresh token with the code
With the code
token (you don’t need to decode it), you can get a refresh token and an access token.
Here is an example API request to /iroh/oauth2/token
using a cURL command (return line here is for readability only):
client_id="client-38bbc74d..."
client_password="FIz1FDf40..."
curl -X POST \
-u "$client_id:$client_password" \
-H 'Accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'User-Agent: ob-http' \
-d 'redirect_uri=https%3A%2F%2Fmy.domain.tld%2Fctr-oauth%2Fcallback.html
&grant_type=authorization_code
&scope=profile%2533inspect
&code=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE1NjQxMzA5NTAsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3VzZXJcL2lkIjoiZjAwMTA5MjQtZTFiYy00YjAzLWI2MDAtODljNmNmNTI3NTdjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vcmdcL2lkIjoiZjQ3YTg5YmYtNWQyZS00MzkyLWI3NzAtYWQ0ODIxYTgyYWNmIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwvZ3JhbnQiOiJhdXRoLWNvZGUiLCJqdGkiOiI2NWU4MGE0Yi03YTM2LTQzNDEtOGI0NC0zZTM2MTk4YjRiMTQiLCJuYmYiOjE1NjQxMzAyOTAsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25hbWUiOiJZYW5uIEVzcG9zaXRvIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2NsaWVudFwvaWQiOiJjbGllbnQtM2JiMWU3ODctMzgxZC00ZjEyLWJmMzItZTExNThmMjAwZGRjIiwiaWF0IjoxNTY0MTMwMzUwLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC9raW5kIjoiY29kZS10b2tlbiJ9.yrOZloNpYGrs0eIWk9dVl-OoSgnSggTcCGrS-iPyhsefZ48SFeoWYtiktki8-uRi6hCjYwQ7WMOQ-MQ9Fr7w4ELMNZJeBSHZjHFty-wH_Fmx62NkVzdAty9pALD2sgqBMS44NWPlyzni1h7sP7wRRxr70o4XdPZUD-wIyjmM0Ewtf0tB-MEPfdXm51na-xt3RAd_hoCP3CubuSPYCDp9dQ-9AOzAAJfogRGboI_u1I38oMY_x_GRZUdyLdOHvVz4XaoBUfRgwS-C7eVu73ULavfJmd5W4UaO_LNV9oNgxQQD9B9JlLs7dMVzFxe6UaYi8KXUdk-qZRD5Px_lth7uVw'
'https://visibility.amp.cisco.com/iroh/oauth2/token'
Here is an example response from the /iroh/oauth2/token
API:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJzdWIiOiJmMDAxMDkyNC1lMWJjLTRiMDMtYjYwMC04OWM2Y2Y1Mjc1N2MiLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE1NjQxMzA5NzMsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3VzZXJcL2lkIjoiZjAwMTA5MjQtZTFiYy00YjAzLWI2MDAtODljNmNmNTI3NTdjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vcmdcL2lkIjoiZjQ3YTg5YmYtNWQyZS00MzkyLWI3NzAtYWQ0ODIxYTgyYWNmIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwvZ3JhbnQiOiJhdXRoLWNvZGUiLCJqdGkiOiI1Y2Y1NGRkMi0zMmNlLTRkOTctODEzYy0wZWFiYzZlZWI1MjEiLCJuYmYiOjE1NjQxMzAzMTMsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25hbWUiOiJZYW5uIEVzcG9zaXRvIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2NsaWVudFwvaWQiOiJjbGllbnQtM2JiMWU3ODctMzgxZC00ZjEyLWJmMzItZTExNThmMjAwZGRjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC92ZXJzaW9uIjoidjEuMjAuMC1kZjgxNGU3YjYyODMwZGRkNTc2ZCIsImlhdCI6MTU2NDEzMDM3MywiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwva2luZCI6ImFjY2Vzcy10b2tlbiJ9.tZ75vCYYst9gSbnZl7LZ3GiVXRpAmOFy9cmUs9wGkSw7XSdRN-4sqwUkcCoNq161piZedf17PrGRMurEtq9x8cW1_YuU_5pi9mDMH1ayQYNXJXkk6G_PJTbzyBLosdp3IAc_GN7DrCZoHx9-oveCy0MfXTbgrjtsx7BoELynECbjTPAfi8CU_rPRCnIyrxLTFMJdqLHsUVP_MDyXEvV43EPw1uRUn9ZBf-dBAswdFsEhH8RF4IFtZyDxb49HTpoWHA54jFWiYAP3cISyS6IKI8H1aVQHAUDbdSzunx0Rp5U9xJysZiAZzVkiSUGTJqXQt_00000000000000000000",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJzdWIiOiJmMDAxMDkyNC1lMWJjLTRiMDMtYjYwMC04OWM2Y2Y1Mjc1N2MiLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE1NjQxMzA5NzMsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3VzZXJcL2lkIjoiZjAwMTA5MjQtZTFiYy00YjAzLWI2MDAtODljNmNmNTI3NTdjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vcmdcL2lkIjoiZjQ3YTg5YmYtNWQyZS00MzkyLWI3NzAtYWQ0ODIxYTgyYWNmIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwvZ3JhbnQiOiJhdXRoLWNvZGUiLCJqdGkiOiI1Y2Y1NGRkMi0zMmNlLTRkOTctODEzYy0wZWFiYzZlZWI1MjEiLCJuYmYiOjE1NjQxMzAzMTMsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25hbWUiOiJZYW5uIEVzcG9zaXRvIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2NsaWVudFwvaWQiOiJjbGllbnQtM2JiMWU3ODctMzgxZC00ZjEyLWJmMzItZTExNThmMjAwZGRjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC92ZXJzaW9uIjoidjEuMjAuMC1kZjgxNGU3YjYyODMwZGRkNTc2ZCIsImlhdCI6MTU2NDEzMDM3MywiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwva2luZCI6ImFjY2Vzcy10b2tlbiJ9.tZ75vCYYst9gSbnZl7LZ3GiVXRpAmOFy9cmUs9wGkSw7XSdRN-4sqwUkcCoNq161piZedf17PrGRMurEtq9x8cW1_YuU_5pi9mDMH1ayQYNXJXkk6G_PJTbzyBLosdp3IAc_GN7DrCZoHx9-oveCy0MfXTbgrjtsx7BoELynECbjTPAfi8CU_rPRCnIyrxLTFMJdqLHsUVP_MDyXEvV43EPw1uRUn9ZBf-dBAswdFsEhH8RF4IFtZyDxb49HTpoWHA54jFWiYAP3cISyS6IKI8H1aVQHAUDbdSzunx0Rp5U9xJysZiAZzVkiSUGTJqXQt_00000000000000000000",
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE3NTE0MTQ0MDAwLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb3JnXC9pZCI6ImY0N2E4OWJmLTVkMmUtNDM5Mi1iNzcwLWFkNDgyMWE4MmFjZiIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2dyYW50IjoiYXV0aC1jb2RlIiwianRpIjoiMjc0YjkwYTAtZDlhNi00YmI2LWJiN2UtMDkzYTY4MzllMTUyIiwibmJmIjoxNTY0MTMwMzEzLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC9zY29wZXMiOlsicHJvZmlsZSIsImluc3BlY3QiXSwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9uYW1lIjoiWWFubiBFc3Bvc2l0byIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvdXNlclwvaWQiOiJmMDAxMDkyNC1lMWJjLTRiMDMtYjYwMC04OWM2Y2Y1Mjc1N2MiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC9jbGllbnRcL2lkIjoiY2xpZW50LTNiYjFlNzg3LTM4MWQtNGYxMi1iZjMyLWUxMTU4ZjIwMGRkYyIsImlhdCI6MTU2NDEzMDM3MywiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwva2luZCI6InJlZnJlc2gtdG9rZW4ifQ.abtBzZmX64XDTB7OJkcyCsOrGnXj-c6tSg89qg9ENnHSeBs-e4AhQMzHO5ZF5Cb4e7c8z34k0gxatuBqLTtLTztV32ktJGZ1IwFA4k7bpPrW1qdrSJQfZjOBBdLG3DSDMqo7dihqh_4VkfZGHDUNfao12xHTXCbzzfKiZNr6f8UJ0lzEvNZ2tQFkIMjdLVrN7OSk5K56-4SwEL6-X7LHRjF8M0FrGq9QU2lztuRyGXfbPOIal4wJdcfZ-Z2S1_fC82y-rE2mEDEX-diCI_oC_01wFiBbklJLoUEYK6Ry0000000000000000000000000000000000000000000000",
"token_type": "bearer",
"expires_in": 600,
"scope": "profile inspect"
}
Notes:
The
-u
of the cURL command automatically encodes the$client_id:$client_password
to base64 and adds it to the header as Basic Auth. If the request is not made with cURL, the Authorization header needs to be Basic Auth, which containsBasic
followed by a base64 encodedCLIENT-ID:CLIENT-PASSWORD
.The body is not JSON. The Content-Type is
application/x-www-form-urlencoded
.The access token will expires in 600 seconds.
Both the
access_token
andrefresh_token
are JWT.Refresh Token
The refresh token is a JWT that once decoded contains:
{
"https://schemas.cisco.com/iroh/identity/claims/user/email":"dev.null@cisco.com",
"https://schemas.cisco.com/iroh/identity/claims/user/nick":"Yann Esposito",
"email":"dev.null@cisco.com",
"iss":"IROH Auth",
"https://schemas.cisco.com/iroh/identity/claims/scopes":[
"profile",
"inspect"
],
"exp":17514144000,
"https://schemas.cisco.com/iroh/identity/claims/oauth/user/id":"f0010924-e1bc-4b03-b600-000000000000",
"https://schemas.cisco.com/iroh/identity/claims/org/id":"f47a89bf-5d2e-4392-b770-000000000000",
"https://schemas.cisco.com/iroh/identity/claims/oauth/grant":"auth-code",
"jti":"64aae4a3-b99b-4215-8f63-c8bf46a4d4b5",
"nbf":1564130650,
"https://schemas.cisco.com/iroh/identity/claims/user/name":"Yann Esposito",
"https://schemas.cisco.com/iroh/identity/claims/user/id":"f0010924-e1bc-4b03-b600-000000000000",
"https://schemas.cisco.com/iroh/identity/claims/oauth/client/id":"client-3bb1e787-381d-4f12-00000000000000000",
"iat":1564130710,
"https://schemas.cisco.com/iroh/identity/claims/oauth/kind":"refresh-token"
}
Your application must save this refresh token for this user.
- Access Token
The access token is also a JWT that you can use to make API requests. In our example, the client asked for the profile
scope that grants access to the route /iroh/profile/whoami
.
ACCESS_TOKEN="eyJhbGciO..."
curl -X 'GET' \
-H 'Accept: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
'https://visibility.amp.cisco.com/iroh/profile/whoami'
Here is an example response from the /iroh/profile/whoami
API:
{
"user":{
"scopes":[
"integration",
"private-intel",
"admin",
"profile",
"inspect",
"iroh-auth",
"sse",
"users",
"cisco",
"casebook",
"enrich",
"oauth",
"global-intel:read",
"collect",
"response",
"ui-settings"
],
"updated-at":"2019-07-25T14:53:21.721Z",
"user-email":"dev.null@cisco.com",
"user-name":"Yann Esposito",
"org-id":"f47a89bf-5d2e-4392-b770-000000000000",
"user-id":"f0010924-e1bc-4b03-b600-000000000000",
"idp-mappings":[
{
"idp":"idb-amp",
"user-identity-id":"f0010924-e1bc-4b03-b600-000000000000",
"organization-id":"f47a89bf-5d2e-4392-b770-000000000000"
}
],
"enabled?":true,
"last-logged-at":[
"2019-07-25T14:53:22.183Z",
"2019-07-25T13:05:50.488Z",
"2019-07-19T14:37:09.021Z",
"2019-07-18T12:11:51.297Z",
"2019-07-12T14:58:36.694Z"
],
"created-at":"2018-09-21T14:52:38.079Z",
"user-nick":"Yann Esposito"
},
"org":{
"scim-status":"activated",
"name":"Cisco - IROH Team",
"updated-at":"2019-07-22T15:27:10.845Z",
"enabled?":true,
"additional-scopes":[
"integration",
"admin",
"sse"
],
"settings":{
"allow-all-role-to-login":false
},
"id":"f47a89bf-5d2e-4392-b770-000000000000",
"created-at":"2018-09-06T04:44:12.512Z"
}
}
- Get a new access token with the refresh token
After a few minutes (10 by default), the access token will expire. At that time, you’ll need to get a new access token, but you shouldn’t ask the user to authorize your application again in IROH.
You can get a new access token by using the /iroh/oauth2/token
API with the refresh token for that user and your client credentials (return line here is for readability only):
client_id="client-38bbc74d..."
client_password="FIz1FDf40..."
curl -X POST \
-u "$client_id:$client_password" \
-H 'Accept: application/json' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'User-Agent: ob-http' \
-d 'grant_type=refresh_token
&scope=profile%2533inspect
&refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE3NTE0MTQ0MDAwLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb3JnXC9pZCI6ImY0N2E4OWJmLTVkMmUtNDM5Mi1iNzcwLWFkNDgyMWE4MmFjZiIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2dyYW50IjoiYXV0aC1jb2RlIiwianRpIjoiMjc0YjkwYTAtZDlhNi00YmI2LWJiN2UtMDkzYTY4MzllMTUyIiwibmJmIjoxNTY0MTMwMzEzLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC9zY29wZXMiOlsicHJvZmlsZSIsImluc3BlY3QiXSwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9uYW1lIjoiWWFubiBFc3Bvc2l0byIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvdXNlclwvaWQiOiJmMDAxMDkyNC1lMWJjLTRiMDMtYjYwMC04OWM2Y2Y1Mjc1N2MiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL29hdXRoXC9jbGllbnRcL2lkIjoiY2xpZW50LTNiYjFlNzg3LTM4MWQtNGYxMi1iZjMyLWUxMTU4ZjIwMGRkYyIsImlhdCI6MTU2NDEzMDM3MywiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwva2luZCI6InJlZnJlc2gtdG9rZW4ifQ.abtBzZmX64XDTB7OJkcyCsOrGnXj-c6tSg89qg9ENnHSeBs-e4AhQMzHO5ZF5Cb4e7c8z34k0gxatuBqLTtLTztV32ktJGZ1IwFA4k7bpPrW1qdrSJQfZjOBBdLG3DSDMqo7dihqh_4VkfZGHDUNfao12xHTXCbzzfKiZNr6f8UJ0lzEvNZ2tQFkIMjdLVrN7OSk5K56-4SwEL6-X7LHRjF8M0FrGq9QU2lztuRyGXfbPOIal4wJdcfZ-Z2S1_fC82y-rE2mEDEX-diCI_oC_01wFiBbklJLoUEYK6RylEQ9lIMgYsUNsw07nM3IWua2cq5O6rNWEe9yJJzo5TIuQg'
'https://visibility.amp.cisco.com/iroh/oauth2/token'
Here is an example response from the /iroh/oauth2/token
API:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL2VtYWlsIjoieWFlc3Bvc2lAY2lzY28uY29tIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9zY29wZXMiOlsiaXJvaC1hZG1pbiIsImludGVncmF0aW9uIiwicHJpdmF0ZS1pbnRlbCIsImFkbWluIiwicHJvZmlsZSIsImluc3BlY3QiLCJpcm9oLWF1dGgiLCJzc2UiLCJ1c2VycyIsImNpc2NvIiwiY2FzZWJvb2siLCJvcmJpdGFsIiwiZW5yaWNoIiwib2F1dGgiLCJnbG9iYWwtaW50ZWwiLCJjb2xsZWN0IiwicmVzcG9uc2UiLCJ1aS1zZXR0aW5ncyJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25pY2siOiJZYW5uIEVzcG9zaXRvIiwiZW1haWwiOiJ5YWVzcG9zaUBjaXNjby5jb20iLCJzdWIiOiJmMDAxMDkyNC1lMWJjLTRiMDMtYjYwMC04OWM2Y2Y1Mjc1N2MiLCJpc3MiOiJJUk9IIEF1dGgiLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJleHAiOjE1NjQxMzQxODksImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3VzZXJcL2lkIjoiZjAwMTA5MjQtZTFiYy00YjAzLWI2MDAtODljNmNmNTI3NTdjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vcmdcL2lkIjoiZjQ3YTg5YmYtNWQyZS00MzkyLWI3NzAtYWQ0ODIxYTgyYWNmIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwvZ3JhbnQiOiJhdXRoLWNvZGUiLCJqdGkiOiIzNmY4YzgxNi1jN2E1LTQ0ZWMtYWZhNS1iMDI4OGIzMzJkZDkiLCJuYmYiOjE1NjQxMzM1MjksImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL3Njb3BlcyI6WyJwcm9maWxlIiwiaW5zcGVjdCJdLCJodHRwczpcL1wvc2NoZW1hcy5jaXNjby5jb21cL2lyb2hcL2lkZW50aXR5XC9jbGFpbXNcL3VzZXJcL25hbWUiOiJZYW5uIEVzcG9zaXRvIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC91c2VyXC9pZCI6ImYwMDEwOTI0LWUxYmMtNGIwMy1iNjAwLTg5YzZjZjUyNzU3YyIsImh0dHBzOlwvXC9zY2hlbWFzLmNpc2NvLmNvbVwvaXJvaFwvaWRlbnRpdHlcL2NsYWltc1wvb2F1dGhcL2NsaWVudFwvaWQiOiJjbGllbnQtM2JiMWU3ODctMzgxZC00ZjEyLWJmMzItZTExNThmMjAwZGRjIiwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC92ZXJzaW9uIjoidjEuMjAuMC1kZjgxNGU3YjYyODMwZGRkNTc2ZCIsImlhdCI6MTU2NDEzMzU4OSwiaHR0cHM6XC9cL3NjaGVtYXMuY2lzY28uY29tXC9pcm9oXC9pZGVudGl0eVwvY2xhaW1zXC9vYXV0aFwva2luZCI6ImFjY2Vzcy10b2tlbiJ9.t8f5cwIBYMYlKSewpCAv2Sgh3xOhQS_MkQqFd14Xz2j9eZD_SpfLRSdYCt5glW9NMiMuUHqtzkYroK46zYeFpy5XoEx3gLZLJC4eJaVdIxRqRxt2IcJ5F7R31Xt_R5Cbkrgncl6NxynTeRyb--4UoQXlTVNmwXQxEGbM1bc9EU7iFabevJVswpj_no9Ah5zp2-BRtvszPzuF9-Ii5AUwmsAoVziH--uezFQQv5xhQNBA17fXjIn5D3oBiK50_vZEaAgdHE3SLDDPqw4BiPzeNipvE6oGuA486Bo3XET_O7DkgzzsEakwZe2HF2DKAstBLJSeMdRjA-fhBrRCLxHJSQ",
"token_type": "bearer",
"expires_in": 600,
"scope": "profile inspect"
}
This is a very similar request to the one that was used with the code
token. The only differences are:
- It uses the
refresh_token
instead of thecode
token. - It uses the
refresh_token
for thegrant_type
parameter.
You must use Basic Auth with your client id and password for authorization, and specify a Content-Type of application/x-www-form-urlencoded
.
Run Demo on localhost
For security, IROH does not allow clients with non https redirect URIs to be approved automatically.
In order to serve HTTPS locally, you should follow the instructions to create a new self signed certificate.
git clone https://github.com/yogsototh/oauth2-client-demo
cd cert
./gen-new-root-cert.sh
./gen-new-cert.sh rootCA
cd ..
You should serve the site/
directory using the created server.crt
and server.key
.
A possible tool is sws. The easiest way to install it is to first install stack and then execute stack install sws
.
You may also need to modify your browser to trust the self-signed certificate.
Checklist
⚠ To verify your integration, follow the Client Checklist.