How to execute multiple CF REST methods with an unique authentication


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

Join cf-dev@lists.cloudfoundry.org to automatically receive all group messages.