To gain access to a user's Avaya Cloud account and make requests to Avaya Spaces on their behalf we must direct them to login to Avaya Cloud Identity using the registered client ID.
Please note: before sending a request, check if all required values in [ ] brackets have been filled in 1. In your browser, go to the following URL (scope request should be one string: 'scope1, scope2, scope3'):
Without PKCE:
https:
With PKCE:
https:
- client_id
- The client ID that was registered
- redirect_uri
- The redirect URL that was registered
- response_type
- code
- access_type
- offline
- scope
- email%20profile%20spaces
- state
- Optional but recommended. A csrf token that adds additional security to prevent unauthorized requests (csrf).
- code_challenge
- Code challenge generated by client application, required for PKCE flow
- code_challenge_method
- 'S256' or 'plain', required for PKCE flow
Scope definitions:
Scope | Definition |
---|
email | Provides access to user’s username / email |
profile | Provides access to user’s profile data |
spaces | Provides access to user’s spaces data |
When the user lands on this page they will be asked to login with one of the following methods:
- Avaya Cloud account
- Google account
- Office365 account
- Salesforce account
- Avaya account
After logging in they will be redirected once more to https://onesnastaging.esna.com/oauth2/authorize/confirm where they will choose to allow or deny the following permissions to your application:
- View and update user email information
- View user detail information
- Call Avaya Spaces APIs
2. Click the "Accept" button
3. You will be taken back to your OAuth2 client predefined redirect_uri. URL will contain the code in it, this code will have to be exchanged for an access_token and id_token
http:
4. To exchange the code received above for the access, id and refresh tokens, the OAuth2 client should make the following request ( this call will return the access_token, id_token, refresh_token):
Without PKCE
curl --location --request POST 'https:
--header 'accept: application/json'
--header 'content-type: application/x-www-form-urlencoded'
--data-urlencode 'client_secret=e6f6eef1023105b0de20963dc2c76059e70bf8b9'
--data-urlencode 'grant_type=authorization_code'
--data-urlencode 'client_id=6702b20d233fdebcf743'
--data-urlencode 'redirect_uri=http:
--data-urlencode 'code=e45d5dddfdabd459ab77fd1d2fa74e9d6891a4a0'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'accept': ' application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
'client_secret': 'e6f6eef1023105b0de20963dc2c76059e70bf8b9',
'grant_type': 'authorization_code',
'client_id': '6702b20d233fdebcf743',
'redirect_uri': 'http:
'code': 'e45d5dddfdabd459ab77fd1d2fa74e9d6891a4a0'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
With PKCE
curl --location --request POST 'https:
--header 'accept: application/json'
--header 'content-type: application/x-www-form-urlencoded'
--data-urlencode 'client_secret=e6f6eef1023105b0de20963dc2c76059e70bf8b9'
--data-urlencode 'grant_type=authorization_code'
--data-urlencode 'client_id=6702b20d233fdebcf743'
--data-urlencode 'redirect_uri=http:
--data-urlencode 'code=e45d5dddfdabd459ab77fd1d2fa74e9d6891a4a0'
--data-urlencode 'code_verifier=Kic8PHRIRBv_K07cr9OQ-7hrFown7zIVGHg8X9KLWYYev__4p0eomZZ61wsVO-PkQDJlC3hbtHXVY_i5Uomc1j4clSqzBPnAiZyq_SMgCYg_edts7GHv50lmgJHfXdfI'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'accept': ' application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
'client_secret': 'e6f6eef1023105b0de20963dc2c76059e70bf8b9',
'grant_type': 'authorization_code',
'client_id': '6702b20d233fdebcf743',
'redirect_uri': 'http:
'code': 'e45d5dddfdabd459ab77fd1d2fa74e9d6891a4a0',
'code_verifier': 'Kic8PHRIRBv_K07cr9OQ-7hrFown7zIVGHg8X9KLWYYev__4p0eomZZ61wsVO-PkQDJlC3hbtHXVY_i5Uomc1j4clSqzBPnAiZyq_SMgCYg_edts7GHv50lmgJHfXdfI'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
5. The access_token will expire in one hour. You can call the API to get a new one like so:
curl --location --request POST 'https:
--header 'accept: application/json'
--header 'content-type: application/x-www-form-urlencoded'
--data-urlencode 'client_secret=e6f6eef1023105b0de20963dc2c76059e70bf8b9'
--data-urlencode 'grant_type=refresh_token'
--data-urlencode 'client_id=6702b20d233fdebcf743'
--data-urlencode 'redirect_uri=http:
--data-urlencode 'refresh_token=bff3e8563fc4723eb667aaf976e0d95983cb634a'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
'client_secret': 'e6f6eef1023105b0de20963dc2c76059e70bf8b9',
'grant_type': 'refresh_token',
'client_id': '6702b20d233fdebcf743',
'redirect_uri': 'http:
'refresh_token': 'bff3e8563fc4723eb667aaf976e0d95983cb634a'
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
6. (OPTIONAL) You can use the id_token to get basic user information from the token by performing a the following GET request:
curl --location --request GET 'https:
--header 'accept: application/json'
--header 'content-type: application/json'
const request = require('request');
let options = {
'method': 'GET',
'url': 'https:
'headers': {
'accept': ' application/json',
'content-type': ' application/json'
},
form: {
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
Example of the response:
{
"expires_in": 3591,
"audience": "6702b20e233fdebcf743",
"user_id": "agxzfm9uZXNuYTIwMTRyEQsSBFVzZXIYgIDQuZ_s1QsH",
"user": {
"username": "test@avaya.com",
"first_name": "Test",
"last_name": "User",
"id": "agxzfm9uZXNuYTIwMTRyEQsSBFVzZXIYgIDQkZ_s1QsM",
"picture_url": "https://onesna.storage.googleapis.com/pictures/pfpic_ltestuser_34cb97bd-0151-449d-84b0-48e07853b..."
},
"issuer": "avayacloud.com"
}
7. To call all other Spaces APIs, use the access_token with Bearer Authorization.
curl --location --request GET 'https:
--header 'accept: application/json'
--header 'content-type: application/json'
--header 'Authorization: Bearer 9e15d37b97d414bc84f9804c32397f1236c2e8ff'
const request = require('request');
let options = {
'method': 'GET',
'url': 'https:
'headers': {
'accept': 'application/json',
'content-type': 'application/json',
'Authorization': 'Bearer 9e15d37b97d414bc84f9804c32397f1236c2e8ff'
},
form: {
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
You should receive a response that looks like this:
{
"name": {
"familyname": "User",
"formatted": "",
"givenname": "Test",
"honorific_prefix": "",
"honorific_suffix": "",
"middlename": "",
"pronunciation": "",
"pronunciation_url": ""
},
"aType": "user",
"permissions": [
"USERSELF_PERMISSION_GROUP",
"IT_ADMIN_PERMISSION_GROUP"
],
"_id": "5f04251caa4a347af9946e06",
"ndbid": "agxzfm9uZXNuYTIwMTRyEQsSBFVzZXIYgIDQuZ_s1QsM",
"addresses": [],
"displayname": "Test",
"emails": [
{
"value": "test@avaya.com",
"type": "",
"primary": true,
"label": "",
"relationdef_id": "agxzfm9uZXNuYTIwMTRyGAsSC1JlbGF0aW9uRGVmGICA0Pmf4cMKDA"
}
],
"gender": "",
"languages": [
{
"code": "en-US",
"primary": true
}
],
"lastupdatetime": "2020-08-03T12:28:05.003Z",
"licenses": [
{
"service_type": "zangspaces_business",
"product_type": "zangspaces",
"expiration": "2300-05-01T16:00:00.000Z",
"parent_type": "company",
"trial": false,
"purchased_license_ndbid": "xgxzfm9uZXNuYTIwMTRyHQsSEFB1cmNoYXNlZExpY2Vuc2UYgICg2MOdtwoM"
}
],
"phone_numbers": [],
"relation_graphs": [
{
"relationdef_id": "agxzfm9uZXNuYTIwMTRyGAsSC1JlbGF0aW9uRGVmGICA0Pmf4cMKDA",
"initiator_id": "5697db96283a4708c4f786f6",
"initiator_type": "company",
"relation_type": "employee"
}
],
"timezone": "",
"username": "test@avaya.com",
"picturefile": "pictures/pfpic_test_34cb97bd-0151-449d-84b0-48e07853b49f",
"picture_url": "https://storage.googleapis.com/onesna/pictures/pfpic_ltest_34cb97bd-0151-449d-84b0-48e07853b...",
"profile": {
"name": {
"familyname": "Test",
"formatted": "",
"givenname": "User",
"honorific_prefix": "",
"honorific_suffix": "",
"middlename": "",
"pronunciation": "",
"pronunciation_url": ""
},
"displayname": "Test User",
"username": "test@avaya.com",
"phone_numbers": [],
"picture_url": "https://storage.googleapis.com/onesna/pictures/pfpic_test_34cb97bd-0151-449d-84b0-48e07853b...",
"addresses": [],
"gender": ""
}
}
8. To allow user to sign out an Oauth2 client.
curl --location --request POST 'https:
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'client_id=TestClientId'
--data-urlencode 'refresh_token=5787989087dnbjkr47898074fjmjkl459900f6761f'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'content-type': 'application/x-www-form-urlencoded',
},
form: {
'client_id': '[client_id]',
'refresh_token': [refresh_token]'
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
Please note: before sending a request, check if all required values in [ ] brackets have been filled in 1. In your browser, go to the following URL (scope request should be one string: 'scope1, scope2, scope3'):
Without PKCE:
https:
With PKCE:
https:
- client_id
- The client ID that was registered
- redirect_uri
- The redirect URL that was registered
- response_type
- code
- access_type
- offline
- scope
- email%20profile%20spaces
- state
- Optional but recommended.
A csrf token that adds additional security to prevent unauthorized requests (csrf).
Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. The server returns the exact value that you send as a name=value pair in the URL query component (?) of the redirect_uri after the user consents to or denies your application's access request.
You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery. Since your redirect_uri can be guessed, using a state value can increase your assurance that an incoming connection is the result of an authentication request.
If you generate a random string or encode the hash of a cookie or another value that captures the client's state, you can validate the response to additionally ensure that the request and response originated in the same browser, providing protection against attacks such as cross-site request forgery.
- code_challenge
- Code challenge generated by client application, required for PKCE flow
- code_challenge_method
- 'S256' or 'plain', required for PKCE flow
Scope definitions:
Scope | Definition |
---|
email | Provides access to user’s username / email |
profile | Provides access to user’s profile data |
spaces | Provides access to user’s spaces data |
When the user lands on this page they will be asked to login with one of the following methods:
- Avaya Cloud account
- Google account
- Office365 account
- Salesforce account
- Avaya account
After logging in they will be redirected once more to https://accounts.avayacloud.com/oauth2/authorize/confirm where they will choose to allow or deny the following permissions to your application:
- View and update user email information
- View user detail information
- Call Avaya Spaces APIs
2. Click the "Accept" button
3. You will be taken back to your OAuth2 client predefined redirect_uri. URL will contain the code in it, this code will have to be exchanged for an access_token and id_token
http:
4. To exchange the code received above for the access, id and refresh tokens, the OAuth2 client should make the following request ( this call will return the access_token, id_token, refresh_token):
curl --location --request POST 'https:
--header 'accept: application/json'
--header 'content-type: application/x-www-form-urlencoded'
--data-urlencode 'client_secret=ce606f2des95cc0ca16b04d8d9ac647a5f17ab3f'
--data-urlencode 'grant_type=authorization_code'
--data-urlencode 'client_id=6702b20d233fdebc743'
--data-urlencode 'redirect_uri=http:
--data-urlencode 'code=[code]'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'accept': ' application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
'client_secret': ce606f2des95cc0ca16b04d8d9ac647a5f17ab3f,
'grant_type': 'authorization_code',
'client_id': '6702b20d233fdebc743',
'redirect_uri': 'http:
'code': [code]'
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
Request and response in POSTMAN:
5. The access_token will expire in one hour. You can call the API to get a new one like so:
curl --location --request POST 'https:
--header 'accept: application/json'
--header 'content-type: application/x-www-form-urlencoded'
--data-urlencode 'client_secret=[client_secret]'
--data-urlencode 'grant_type=refresh_token'
--data-urlencode 'client_id=[client_id]'
--data-urlencode 'redirect_uri=http:
--data-urlencode 'refresh_token=[refresh_token]'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'accept': 'application/json',
'content-type': 'application/x-www-form-urlencoded'
},
form: {
'client_secret': [client_secret],
'grant_type': 'refresh_token',
'client_id': '[client_id]',
'redirect_uri': 'http:
'refresh_token': '[refresh_token]'
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
6. (OPTIONAL) You can use the id_token to get basic user information from the token by performing a the following GET request:
curl --location --request GET 'https:
--header 'accept: application/json'
--header 'content-type: application/json'
const request = require('request');
let options = {
'method': 'GET',
'url': 'https:
'headers': {
'accept': ' application/json',
'content-type': ' application/json'
},
form: {
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
Example of the response:
{
"expires_in": 3591,
"audience": "6702b20e233fdebcf743",
"user_id": "agxzfm9uZXNuYTIwMTRyEQsSBFVzZXIYgIDQuZ_s1QsH",
"user": {
"username": "test@avaya.com",
"first_name": "Test",
"last_name": "User",
"id": "agxzfm9uZXNuYTIwMTRyEQsSBFVzZXIYgIDQkZ_s1QsM",
"picture_url": "https://onesna.storage.googleapis.com/pictures/pfpic_ltestuser_34cb97bd-0151-449d-84b0-48e07853b..."
},
"issuer": "avayacloud.com"
}
7. To call all other Spaces APIs, use the access_token with Bearer Authorization.
curl --location --request GET 'https:
--header 'accept: application/json'
--header 'content-type: application/json'
--header 'Authorization: Bearer [access_token]'
const request = require('request');
let options = {
'method': 'GET',
'url': 'https:
'headers': {
'accept': 'application/json',
'content-type': 'application/json',
'Authorization': 'Bearer [access_token]'
},
form: {
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});
You should receive a response that looks like this:
{
"name": {
"familyname": "User",
"formatted": "",
"givenname": "Test",
"honorific_prefix": "",
"honorific_suffix": "",
"middlename": "",
"pronunciation": "",
"pronunciation_url": ""
},
"aType": "user",
"permissions": [
"USERSELF_PERMISSION_GROUP",
"IT_ADMIN_PERMISSION_GROUP"
],
"_id": "5f04251caa4a347af9946e06",
"ndbid": "agxzfm9uZXNuYTIwMTRyEQsSBFVzZXIYgIDQuZ_s1QsM",
"addresses": [],
"displayname": "Test",
"emails": [
{
"value": "test@avaya.com",
"type": "",
"primary": true,
"label": "",
"relationdef_id": "agxzfm9uZXNuYTIwMTRyGAsSC1JlbGF0aW9uRGVmGICA0Pmf4cMKDA"
}
],
"gender": "",
"languages": [
{
"code": "en-US",
"primary": true
}
],
"lastupdatetime": "2020-08-03T12:28:05.003Z",
"licenses": [
{
"service_type": "zangspaces_business",
"product_type": "zangspaces",
"expiration": "2300-05-01T16:00:00.000Z",
"parent_type": "company",
"trial": false,
"purchased_license_ndbid": "xgxzfm9uZXNuYTIwMTRyHQsSEFB1cmNoYXNlZExpY2Vuc2UYgICg2MOdtwoM"
}
],
"phone_numbers": [],
"relation_graphs": [
{
"relationdef_id": "agxzfm9uZXNuYTIwMTRyGAsSC1JlbGF0aW9uRGVmGICA0Pmf4cMKDA",
"initiator_id": "5697db96283a4708c4f786f6",
"initiator_type": "company",
"relation_type": "employee"
}
],
"timezone": "",
"username": "test@avaya.com",
"picturefile": "pictures/pfpic_test_34cb97bd-0151-449d-84b0-48e07853b49f",
"picture_url": "https://storage.googleapis.com/onesna/pictures/pfpic_ltest_34cb97bd-0151-449d-84b0-48e07853b...",
"profile": {
"name": {
"familyname": "Test",
"formatted": "",
"givenname": "Lukas",
"honorific_prefix": "",
"honorific_suffix": "",
"middlename": "",
"pronunciation": "",
"pronunciation_url": ""
},
"displayname": "Test User",
"username": "test@avaya.com",
"phone_numbers": [],
"picture_url": "https://storage.googleapis.com/onesna/pictures/pfpic_test_34cb97bd-0151-449d-84b0-48e07853b...",
"addresses": [],
"gender": ""
}
}
8. To allow user to sign out an Oauth2 client.
curl --location --request POST 'https:
--header 'Content-Type: application/x-www-form-urlencoded'
--data-urlencode 'client_id=TestClientId'
--data-urlencode 'refresh_token=5787989087dnbjkr47898074fjmjkl459900f6761f'
const request = require('request');
let options = {
'method': 'POST',
'url': 'https:
'headers': {
'content-type': 'application/x-www-form-urlencoded',
},
form: {
'client_id': '[client_id]',
'refresh_token': [refresh_token]'
}
};
request(options, (error, response) => {
if (error) throw new Error(error);
console.log(response.body);
});