OAuth2 Authorization Code Grant Credentials (Web Applications)
The OAuth2 Authorization Code Grant is described in the RFC6749. This provides the ability for a user to grant access to your web application. Your application will be able to make the API requests on behalf of multiple users. This is both easier and more secure than the client credentials grant.
With this workflow, the user will not need to copy/paste any credentials and just click a button to authorize the client.
An authorization code grant credential workflow follows these steps:
Create a single client for your application.
Note: This should only be done once.
Put a link on your web application. When the user clicks on the link, they are redirected to IROH, and they can grant access to your application. The user returns to your web application with a secret code and you can retrieve a refresh token that you should keep securely.
Note: This should only be done once per user.
With the refresh token, you can retrieve an access token without user interaction.
Note: This should only be done when you want to call the API and the access token has expired (every 10 minutes by default).
The access token is used to call the IROH APIs on behalf of the user.
Note: This should be done for all API calls. We recommend to 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 Authorization Code Grant client, read this section in its entirety to determine the correct client configuration settings.
Mandatory Configuration Settings
- 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’ll 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 won’t 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 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 to everyone
. 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 be https
. 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
to public
.
This is also a very 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
and refresh-token-lifetime-in-sec
when creating your client. You will need to request a IROH administrator approve your client.
After a refresh-token lifetime, the refresh token will not work anymore. After half the lifetime, when getting a new access token, you will also get an updated refresh token with the same lifetime. It is then up to you to perform a new refresh token call during the second half or one 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 re-engage 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 Mandatory Configuration Settings 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 the criterias are met. If some criterias are not met, the client is created but disabled until it has been approved by an administrator.
For details on how to create OAuth Code Client credentials, see API Clients.
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 interface will provide 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’re allowed to access.
To get the list of scopes, use the /iroh/profile/whoami
API:
Open the
whoami
API Swagger UI interface: 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 either with a IROH login, apiKey, or OAuth2 credentials.
Click Try it out to the right of Parameters.
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 create the client.
To use the /iroh/oauth2-clients/clients
API:
- Open the
clients
API Swagger UI interface: https://visibility.amp.cisco.com/iroh/oauth2-clients/index.html#/OAuth2Client/post_iroh_oauth2_clients_clients. - Click Try it out to the right of Parameters.
- 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 the Server response section, 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 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 scopes required for your application
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
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. (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, you must 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
. 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...",
"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 on the server and not within 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 shouldn’t expire soon. Make sure to save the refresh token for your user. Each time you need a new access token, you’ll 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" ],
"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"
],
"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" ];
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 is
https://my.domain.tld/ctr-oauth/index.html
. - Click 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"
],
"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",
"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 minutes by default), the access token will expire. At that time, you will need to get a new access token, but you should not 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'
The following 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 Simple Web Server
(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.