Register ArcGIS Server token with IdentityManager

17048
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
1 Solution

Accepted Solutions
JeffPace
MVP Alum

we do this with tokens

var idObject ={};
                                idObject.serverInfos= [serverInfo];
                                var credentials={};
                                credentials.userId = "util";
                                credentials.server = window.location.protocol+'//'+window.location.hostname+'/arcgis03';
                                credentials.token = tokenInfo.token;
                                credentials.expires = expirationTime;
                                credentials.ssl = false;
                                credentials.scope = "server";
                                credentials.validity = 720;
                                credentials.creationTime = creationTime;
                                
                                
                                idObject.credentials = [credentials];
                               //credential object is correct
                                esri.id.initialize(idObject);
                                esri.id.tokenValidity=720;

View solution in original post

0 Kudos
12 Replies
DavidBlanchard
Esri Contributor

Unfortunately, there isn't an easy way to just pass a token and let JavaScript do the rest of the work. The Identity Manager is meant to process the authentication.

You need to use the initialize method of the Identity Manager, passing it the Identity Manager properties which look like:

{
    "serverInfos": [
        {
            "server": "https://myserver.com",
            "tokenServiceUrl": "https://myserver.com/arcgis/tokens/",
            "adminTokenServiceUrl": "https://myserver.com/arcgis/admin/generateToken",
            "shortLivedTokenValidity": 60,
            "currentVersion": 10.3,
            "hasServer": true
        }
    ],
    "oAuthInfos": [],
    "credentials": [
        {
            "userId": "username",
            "server": "https://avl.esri.ca:8013",
            "token": "e1jf-6cd-a2whk5_3h4ZWKnCxd1LyVy_eMLsuvxxPd3.",
            "expires": 1421264556065,
            "validity": 60,
            "ssl": false,
            "creationTime": 1421260956120,
            "scope": "server",
            "resources": [
                "https://myserver.com/arcgis/rest/services"
            ]
        }
    ]
}

This object can be tricky to build, but most of the info can be obtained from the token request and combining it with the information available from the server information query: http://myserver.com/arcgis/rest/info?f=json

JeffPace
MVP Alum

we do this with tokens

var idObject ={};
                                idObject.serverInfos= [serverInfo];
                                var credentials={};
                                credentials.userId = "util";
                                credentials.server = window.location.protocol+'//'+window.location.hostname+'/arcgis03';
                                credentials.token = tokenInfo.token;
                                credentials.expires = expirationTime;
                                credentials.ssl = false;
                                credentials.scope = "server";
                                credentials.validity = 720;
                                credentials.creationTime = creationTime;
                                
                                
                                idObject.credentials = [credentials];
                               //credential object is correct
                                esri.id.initialize(idObject);
                                esri.id.tokenValidity=720;
0 Kudos
deleted-user-RAnWn8DDSd1P
New Contributor III

Indeed combining server info and credentials and using esri.id.initialize() worked!  Much appreciated Jeff and David

0 Kudos
JonMorris2
Occasional Contributor II

So, having called initialize, a token is supposed to be appended to every service call? That isn't happening for me.

I've tried various ways of calling initialize and it seems to work ok, but when I load a map service in the next line, I get a credential popup.

mapLayer0 = new ArcGISDynamicMapServiceLayer(serviceURL);

The developer console shows Error: Token Required, with the call stack leading way down into init.js.

0 Kudos
deleted-user-RAnWn8DDSd1P
New Contributor III

So, I just noticed that after the ArcGIS Server token goes invalid, the console just errors "Invalid Token".  In the documentation for IdentityManager there's mention of a timer that automatically refreshes the token.  Can this be done automatically with a particular setting in the credential object?

0 Kudos
JeffPace
MVP Alum
setInterval(lang.hitch(this, function () {
                                    var def = esri.id.generateToken(serverInfo, {"username": "util", "password": "<>"});


                                def.addCallback(lang.hitch(this, function (tokenInfo) {
                                   
  //var idBase = new IdentityManagerBase();
        //get token creation time in epoch
                                var creationTime = (new Date).getTime();
                                                //calculate the token expiration based on short lived token validity
                                var expirationTime = creationTime + (serverInfo.shortLivedTokenValidity * 60000);
                              // alert(creationTime+":"+expirationTime)
                                                //create array of secured services
                                // create a new javascript Date object based on the timestamp
                                // multiplied by 1000 so that the argument is in milliseconds, not seconds
                                         
                                 
                                var idObject ={};
                                idObject.serverInfos= [serverInfo];
                                var credentials={};
                                credentials.userId = "util";
                                credentials.server = window.location.protocol+'//'+window.location.hostname+'/arcgis03';
                                credentials.token = tokenInfo.token;
                                credentials.expires = expirationTime;
                                credentials.ssl = false;
                                credentials.scope = "server";
                                credentials.validity = 720;
                                credentials.creationTime = creationTime;
                               
                               
                                idObject.credentials = [credentials];
                              //credential object is correct
                                esri.id.initialize(idObject);
                                esri.id.tokenValidity=720;

                                }));
                               }, 3000000));
0 Kudos
deleted-user-RAnWn8DDSd1P
New Contributor III

I fetch the token server-side so username/password is not discoverable on the client.  The way the documentation reads I thought that given there was currently valid token, IdentityManager could use it to fetch a new one when the period was nearing its end.  I could just set a meta refresh less than the token validity period I suppose.

0 Kudos
KellyHutchins
Esri Frequent Contributor

Have you thought about setting up and using a proxy? It will handle getting and refreshing the token for you. The proxy source and instructions for setting up the proxy can be found here: Esri/resource-proxy · GitHub

0 Kudos
BhavinSanghani
Occasional Contributor II

Hi Aaron,

Did this approach work for you further? I implemented following way but IdentityManager tries to refresh token periodically. 

I have an enterprise application where I have 600+ screens. In that only 4-5 gis screens. Whenever I connect secure gis map service from gis screen then:

- Generate token from server side and pass it to client side

- Initialize credentials and serverInfos in IdentityManager.initialize() method.

- Start the task with lesser than shortLivedTokenValidity (available at http://<arcgisserver>/rest/info resource) and re-initialize identity manager with the new token.

- This works fine and loads the map.

- Once I leave the GIS screen then I need to stop the task that I initiated as it has no use. 

- At this point there is an issue. IdentityManager is monitoring based for token expiry. Once it's expired then it tries to refresh the token. Since it doesn't find credentials (as password is not passed to client side), it opens up the popup.

- Let's say if I destroy the credentials while leaving (using esriId.destroyCredentials()) and revisit the GIS screen then also it opens up the popup because it has been initialized with esri.id. 

Did you fall in the same situation? How could you resolve it? Wondering if I can destroy esri.id somehow while leaving the GIS screen. Tried to do esri.id = null but no success. Still the popup opens up when I revisit the screen.

jeff.pace / khutchins-esristaff / dblanchardesri-ca-esridist - any suggestions? I cannot work with proxy as I need to set credentials for each user. 

0 Kudos