Register ArcGIS Server token with IdentityManager

17203
12
Jump to solution
01-13-2015 01:54 PM
deleted-user-RAnWn8DDSd1P
New Contributor III

We have a protected ArcGIS Online webmap which references some of our protected ArcGIS Server services on-premise.  I'm trying to bypass both challenges for credentials with IdentityManager.  Server-side I fetch an oauth2 token from ArcGIS Online with client_id and client_secret and a token from our on-premise ArcGIS Server with username and password.  I've been successful using the following to register the oauth2 token:

var agolToken = {

   'server': 'http://www.arcgis.com/sharing/rest',

   'userId': 'user',

   'token': '<fetched ArcGIS Online oauth2 access_token>',

   'ssl': true,

   'expires': <fetched ArcGIS Online oauth2 expires_in>

};

esriIdentityManager.registerToken(agolToken);

esriArcgisUtils.createMap('<protected ArcGIS Online webmap id>',...

How do I register the ArcGIS Server token with IdentityManager such that every subsequent request, tile or otherwise, will append the token?

I was able to interrupt some requests with esri.setRequestPreCallback and add the token to ioArgs.url, but the tile requests do not seem to filter through there. 

0 Kudos
12 Replies
DavidBlanchard
Esri Contributor

Hi Bhavin,

I would suggest generating a token with a longer life if you can. This is by far the easiest way to go about keeping a custom "session" active.

However, if you absolutely must keep the solution running beyond the lifespan of a token that you manually added, then read-on. Please note however that this is a hack and is not supported. I make no warranty of fitness or completeness of any kind, express or implied; proceed at your own risk.

The first thing to understand is that the token is stored in multiple places, all of which are maintained by the Identity Manager. Tokens are stored in the Identity Manager for new layers, and is stored in each layer for use in new queries. This is in addition to any tasks (e.g. QueryTask) that you have setup. If you want to continue using the map after the token has expired, you will need to supply a new token to these objects. Otherwise, attempting to update any existing layers or add a new layer will cause a login popup to show up.

Secondly, the Identity Manager will automatically attempt to refresh your token once it expires through a timer.

The code below applies to the 2.x API.

Updating the Identity Manager's Token

You can access the token, expires, and creationTime properties of your credentials to update them. An example is shown below:

//Loop through the credentials array
IdentityManager.credentials.forEach(function(creds, i) {
  //Look for the server whos credentials you want to update
  if (creds.server === myServer) {
    //Update the credentials
    //(result would be your token object previously obtained)
    IdentityManager.credentials[i].token = result.token;
    IdentityManager.credentials[i].expires = result.expires;
    IdentityManager.credentials[i].creationTime = result.creationTime;
  }
});‍‍‍‍‍‍‍‍‍‍

Cancel the automated refresh of the credentials

Each credential item in the Identity Manager has a timeout which will trigger a token refresh upon expiration. Below is an example of how to cancel this timer.

//Loop through the credentials array
IdentityManager.credentials.forEach(function(creds, i) {
  //Ensure the credentials are for my server
  if (creds.server === myServer) {
    //Cancel the timer
    clearTimeout(creds._refreshTimer);
  }
});

Update tokens in layers

Updating the Identity Manager does not update the layers (and tasks), so you have to do that manually.

//Retrieve the layer object
var layer = map.getLayer("myLayerID");

//Update the layer's credentials
//(result is the previously obtained token)
layer.credential.token = result.token;
layer.credentials.expires = result.expires;
layer.credentials.creationTime = result.creationTime;
BhavinSanghani
Occasional Contributor II

Hi David,

Thanks for the detailed explanation on this. I tested the code you suggested under "Cancel the automated refresh of the credentials" and it worked for my flow!

0 Kudos
AdrianMarsden
Occasional Contributor III

Sorry for hijacking thread, but I'm trying to do what David said would be the better option "generating a token with a longer life if you can" - I want to only ask the users for ID once, ever, well, in practice once a decade (see https://community.esri.com/thread/225898-identity-manager-ask-once-a-decade-for-username

I have put a very long "expires" in, and my "IdString" that gets sent to the Identity Manager is

{"serverInfos":[{"server":"https://mymaps.com/arcgis","tokenServiceUrl":"https:/maymaps.com/arcgis/tokens/","adminTokenServiceUrl":"https://mymaps.com/arcgis/admin/generateToken","shortLivedTokenValidity":10080,"currentVersion":10.31,"hasServer":true}],"oAuthInfos":[],"credentials":[{"userId":"myname","server":"https://mymaps.com/arcgis","token":"BOiXMC8EfP36sEMIOXs18HwjcEnRy0n1qPeIA4ukkuo.","expires":1735689600000,"validity":5256000,"ssl":false,"creationTime":1556203552770,"scope":"server","resources":["https://mymaps.com/arcgis/rest/services/LIVEinternal/EH_tasks/MapServer"]}]}

But it still "forgets" by the next day.

Any ideas?

Cheers


ACM

0 Kudos