How to execute multiple CF REST methods with an unique authentication


James Bayer
 

* access tokens have a short time to live, something usually measured in
minutes, and generally are not revokable by the issuer as endpoints do not
check in with the issuer when making decisions
* refresh tokens have a longer time to love, usually hours or days, and can
be used to get new access tokens. refresh tokens are revokable.

use base64 to decode the token and you'll see the attributes.

On Mon, Sep 7, 2015 at 11:40 PM, Juan Antonio Breña Moral <
bren(a)juanantonio.info> wrote:

Hi,

you had reason. I stored in the right way the token, and Now it is
possible to reuse a token for multiple operations.

Example:

it.only("Using An unique Login, it is possible to execute 3 REST
operations", function () {
this.timeout(2500);

CloudFoundry.setEndPoint(endPoint);

var token_endpoint = null;
var refresh_token = null;
var token_type = null;
var access_token = null;
return CloudFoundry.getInfo().then(function (result) {
token_endpoint = result.token_endpoint;
return CloudFoundry.login(token_endpoint, username, password);
}).then(function (result) {
token_type = result.token_type;
access_token = result.access_token;
return CloudFoundryApps.getApps(token_type, access_token);
}).then(function (result) {
return CloudFoundryApps.getApps(token_type, access_token);
}).then(function (result) {
return CloudFoundryApps.getApps(token_type, access_token);
}).then(function (result) {
expect(true).to.equal(true);
});
});

What is the usage of token_refresh?
How to check the pending time for current token?

Juan Antonio


--
Thank you,

James Bayer


Juan Antonio Breña Moral <bren at juanantonio.info...>
 

Hi,

you had reason. I stored in the right way the token, and Now it is possible to reuse a token for multiple operations.

Example:

it.only("Using An unique Login, it is possible to execute 3 REST operations", function () {
this.timeout(2500);

CloudFoundry.setEndPoint(endPoint);

var token_endpoint = null;
var refresh_token = null;
var token_type = null;
var access_token = null;
return CloudFoundry.getInfo().then(function (result) {
token_endpoint = result.token_endpoint;
return CloudFoundry.login(token_endpoint, username, password);
}).then(function (result) {
token_type = result.token_type;
access_token = result.access_token;
return CloudFoundryApps.getApps(token_type, access_token);
}).then(function (result) {
return CloudFoundryApps.getApps(token_type, access_token);
}).then(function (result) {
return CloudFoundryApps.getApps(token_type, access_token);
}).then(function (result) {
expect(true).to.equal(true);
});
});

What is the usage of token_refresh?
How to check the pending time for current token?

Juan Antonio


CF Runtime
 

A token should be valid for any number of requests until the expiration
time is reached.

In your code example, is the "result" passed to your second call to
"getApps" the result from the login attempt, or the result from the first
"getApps" call? You might try console.log(results) before that second
getApps call.

Joseph
OSS Release Integration Team

On Mon, Sep 7, 2015 at 3:05 AM, Juan Antonio Breña Moral <
bren(a)juanantonio.info> wrote:

Currently,

If I execute 2 operations with the same token, I receive the following
message:

it.only("Using Login to execute 2 REST operations", function () {
this.timeout(2500);

CloudFoundry.setEndPoint(endPoint);

var token_endpoint = null;
var refresh_token = null;
return CloudFoundry.getInfo().then(function (result) {
token_endpoint = result.token_endpoint;
return CloudFoundry.login(token_endpoint, username, password);
}).then(function (result) {
return CloudFoundryApps.getApps(result.token_type,
result.access_token);
}).then(function (result) {
return CloudFoundryApps.getApps(result.token_type,
result.access_token);
}).then(function (result) {
console.log(result);
expect(true).to.equal(true);
});
});

Tests Response:

1) Cloud Foundry Using Login to execute 2 REST operations:
Error: the string "{\n \"code\": 10002,\n \"description\":
\"Authenticati
on error\",\n \"error_code\": \"CF-NotAuthenticated\"\n}\n" was thrown,
throw a
n Error :)


Juan Antonio Breña Moral <bren at juanantonio.info...>
 

Currently,

If I execute 2 operations with the same token, I receive the following message:

it.only("Using Login to execute 2 REST operations", function () {
this.timeout(2500);

CloudFoundry.setEndPoint(endPoint);

var token_endpoint = null;
var refresh_token = null;
return CloudFoundry.getInfo().then(function (result) {
token_endpoint = result.token_endpoint;
return CloudFoundry.login(token_endpoint, username, password);
}).then(function (result) {
return CloudFoundryApps.getApps(result.token_type, result.access_token);
}).then(function (result) {
return CloudFoundryApps.getApps(result.token_type, result.access_token);
}).then(function (result) {
console.log(result);
expect(true).to.equal(true);
});
});

Tests Response:

1) Cloud Foundry Using Login to execute 2 REST operations:
Error: the string "{\n \"code\": 10002,\n \"description\": \"Authenticati
on error\",\n \"error_code\": \"CF-NotAuthenticated\"\n}\n" was thrown, throw a
n Error :)


Juan Antonio Breña Moral <bren at juanantonio.info...>
 

Hi,

Currently, I am developing a Web Application which interacts with CF REST API. At the moment, I have to log in the system every time when I execute any REST operation.

Example:

function createApp(appName, buildPack) {

var token_endpoint = null;
var app_guid = null;
var space_guid = null;
var domain_guid = null;
var routeName = null;
var route_guid = null;
var route_create_flag = false;

return new Promise(function (resolve, reject) {

CloudFoundry.getInfo().then(function (result) {
token_endpoint = result.token_endpoint;

return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundrySpaces.getSpaces(result.token_type, result.access_token).then(function (result) {
return new Promise(function (resolve) {
space_guid = result.resources[0].metadata.guid;
//console.log("Space guid: ", space_guid);
return resolve();
});
});
});
//Does exist the application?
}).then(function () {
var filter = {
'q': 'name:' + appName,
'inline-relations-depth': 1
};
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundrySpaces.getSpaceApps(result.token_type, result.access_token, space_guid, filter);
});
}).then(function (result) {

//If exist the application, Stop
if (result.total_results === 1) {
console.log("Stop App: " + appName);
app_guid = result.resources[0].metadata.guid;
console.log("App guid: ", app_guid);
console.log(result.resources[0].entity.name);

return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryApps.stopApp(result.token_type, result.access_token, app_guid);
});
}else {
//console.log("Create App");
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryApps.createApp(result.token_type, result.access_token, appName, space_guid, buildPack).then(function (result) {
return new Promise(function (resolve) {
//console.log(result);
app_guid = result.metadata.guid;
return resolve();
});
});
});
}
}).then(function () {
//TODO: How to make the inference?
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryDomains.getSharedDomains(result.token_type, result.access_token);
});
}).then(function () {
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryDomains.getDomains(result.token_type, result.access_token).then(function (result) {
return new Promise(function (resolve) {
domain_guid = result.resources[0].metadata.guid;
//console.log("Domain guid: " , domain_guid);
return resolve();
});
});
});
}).then(function () {
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryRoutes.checkRoute(result.token_type, result.access_token, appName, domain_guid).then(function (result) {
return new Promise(function (resolve) {
if (result.total_results === 1) {
console.log("Exist a Route");
//console.log(result.resources);
route_guid = result.resources[0].metadata.guid;
console.log("Route guid: ", route_guid);
return resolve(result);
}else {
//Add Route
route_create_flag = true; //Workaround
return resolve();
}

});
});
});
}).then(function () {
//TODO: Refactor syntax to code in the right place
if (route_create_flag) {
//Add Route
//console.log("Create a Route");
routeName = appName;
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryRoutes.addRoute(result.token_type, result.access_token, domain_guid, space_guid, routeName).then(function (result) {
return new Promise(function (resolve) {
//console.log(result);
route_guid = result.metadata.guid;
return resolve(result);
});
});
});
}else {
return new Promise(function (resolve) {
return resolve();
});
}
}).then(function () {
return CloudFoundry.login(token_endpoint, username, password).then(function (result) {
return CloudFoundryApps.associateRoute(result.token_type, result.access_token, appName, app_guid, domain_guid, space_guid, route_guid);
});
}).then(function (result) {
//console.log(result);
return resolve(result);
}).catch(function (reason) {
console.error("Error: " + reason);
return reject(reason);
});

});

}

The login method sends the following parameters in the requests to uaa:

var options = {
method: 'POST',
url: url,
headers: {
'Authorization': 'Basic Y2Y6',
'Content-Type': 'application/x-www-form-urlencoded'
},
form : {
grant_type: "password",
client_id: "cf",
username: username,
password: password
}
};

When I log into CF I receive the following response:

{ access_token: 'eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI4YzRkMDRmMC1iYmU4LTRjNWUtODFmMS
04Y2M5ZDc4Y2ZhZDciLCJzdWIiOiIwNTQ0ODY5MS04YWU1LTQwZDktODU2Mi1kOWI4N2E2MTJiMzMiLC
JzY29wZSI6WyJzY2ltLnJlYWQiLCJjbG91ZF9jb250cm9sbGVyLmFkbWluIiwic2NpbS53cml0ZSIsIm
Nsb3VkX2NvbnRyb2xsZXIud3JpdGUiLCJwYXNzd29yZC53cml0ZSIsIm9wZW5pZCIsImNsb3VkX2Nvbn
Ryb2xsZXIucmVhZCIsImRvcHBsZXIuZmlyZWhvc2UiXSwiY2xpZW50X2lkIjoiY2YiLCJjaWQiOiJjZi
IsImF6cCI6ImNmIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjA1NDQ4NjkxLThhZT
UtNDBkOS04NTYyLWQ5Yjg3YTYxMmIzMyIsInVzZXJfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbi
IsImlhdCI6MTQ0MTYxODAyOCwiZXhwIjoxNDQxNjE4NjI4LCJpc3MiOiJodHRwczovL3VhYS4zNy40OC
44MS4xNzAueGlwLmlvL29hdXRoL3Rva2VuIiwiYXVkIjpbImNmIiwic2NpbSIsImNsb3VkX2NvbnRyb2
xsZXIiLCJwYXNzd29yZCIsIm9wZW5pZCIsImRvcHBsZXIiXX0.W8_LC1g5eNM8NWVh68Pfx5FKVQe6C6
bvEulELHG9_9qsy3A3S50tUKNFQNjIhBPR18DyAJvs5iQy1pEcU2AciRa_3w83nLnzsgIJgwEFQ4mlCK
j9ovpsE55cM2-5JpFgBi8b-em-ce4WwSvFN9y1BhOAc2njNdJKJllR5Gh5kPE',
token_type: 'bearer',
refresh_token: 'eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI0ZGViNjE3Yy00NDMxLTQzYTQtODU5Y
y1hNWQ1MmIwNTI4ZTIiLCJzdWIiOiIwNTQ0ODY5MS04YWU1LTQwZDktODU2Mi1kOWI4N2E2MTJiMzMiL
CJzY29wZSI6WyJzY2ltLnJlYWQiLCJjbG91ZF9jb250cm9sbGVyLmFkbWluIiwic2NpbS53cml0ZSIsI
mNsb3VkX2NvbnRyb2xsZXIud3JpdGUiLCJwYXNzd29yZC53cml0ZSIsIm9wZW5pZCIsImNsb3VkX2Nvb
nRyb2xsZXIucmVhZCIsImRvcHBsZXIuZmlyZWhvc2UiXSwiaWF0IjoxNDQxNjE4MDI4LCJleHAiOjE0N
DQyMTAwMjgsImNpZCI6ImNmIiwiaXNzIjoiaHR0cHM6Ly91YWEuMzcuNDguODEuMTcwLnhpcC5pby9vY
XV0aC90b2tlbiIsImdyYW50X3R5cGUiOiJwYXNzd29yZCIsInVzZXJfbmFtZSI6ImFkbWluIiwidXNlc
l9pZCI6IjA1NDQ4NjkxLThhZTUtNDBkOS04NTYyLWQ5Yjg3YTYxMmIzMyIsImF1ZCI6WyJjZiIsInNja
W0iLCJjbG91ZF9jb250cm9sbGVyIiwicGFzc3dvcmQiLCJvcGVuaWQiLCJkb3BwbGVyIl19.ji7tWinO
U1Wq6Y77ygSdF12ETG_TD9xQf82bVU01si3OZ9Ou4FG_HWv-CvQlJ7yh1KpH8emGsz92Omu45YEOyNU7
dOIRIMtP7u2DO_aWb2mzMBOwVnpFongyRkz_lbnqPgixW88v1DOJ2PY5KYoNxzxbIP98UX2xht6XXSqO
qww',
expires_in: 599,
scope: 'scim.read cloud_controller.admin scim.write cloud_controller.write pas
sword.write openid cloud_controller.read doppler.firehose',
jti: '8c4d04f0-bbe8-4c5e-81f1-8cc9d78cfad7' }


How to use the refresh token?
It is possible to reuse some fields of login response to reuse the authentication?

My idea could be:

1. Login in the system.
2. Call CF API n times, sending some kind of token.

At the moment, I send in the authorization header the auth token:

var options = {
method: 'GET',
url: url,
headers: {
'Authorization': token_type + ' ' + access_token
}
};

Many thanks in advance.

Juan Antonio