Bypass user login dialog and automatically signing a user account

21706
21
06-28-2013 10:58 AM
ScottGrace
New Contributor III
I need to automatically sign in a user without requiring them to enter the username and password for the ArcGIS online account. I have a user name and password that i want to be able to use everytime a user tries to view a web app that is only viewable to an organization. When it is only visible to the organization you are required to sign in, i want to bypass the process and automatically login a user. I know that i need to use the token feature but im unable to make that work... here is what i have:

<script type="text/javascript">
      dojo.require("utilities.App");
      dojo.require("templateConfig.commonConfig");
      
      
        dojo.require("dojo.parser");
        dojo.require("esri.IdentityManager");
        var cred = "esri_jsapi_id_manager_data";
        var shortLivedTokenValidity=60;
        function init() {

            var idBase = new esri.IdentityManagerBase();
            //esri.config.defaults.io.proxyUrl = "proxy.ashx";
            var serverInfo = {
                server: "http://myserver:port",
                tokenServiceUrl: "http://myserver/arcgis/tokens",
                currentVersion: 10.1
            };
            var def = idBase.generateToken(serverInfo, { username: "user1", password: "user1" });
            def.addCallback(function (tokenInfo) {
        var idBase = new esri.IdentityManagerBase();
        //Short lived token is valid for 60 mins by defult 
                idBase.tokenValidity =shortLivedTokenValidity=60;
                var serverInfo = {
                    server: "http://myserver:port",
                    tokenServiceUrl: "http://myserver/arcgis/tokens/",
                    currentVersion: 10.1
                };
                
                esri.id.registerServers([serverInfo]);
               //get token creation time in epoch
                var creationTime = (new Date).getTime();
        //calculate the token expiration based on short lived token validity
                var expirationTime = creationTime + (shortLivedTokenValidity * 60000);
        //create array of secured services 
                var securedServices = [];
                for (var services in this.configData.mapService) {
                    securedServices.push(this.configData.mapService[services]);
                }
                var idString = dojo.toJson({ serverInfos: [serverInfo],
                    credentials: [{
                        userId: user1,
                        server: "http://myserver:port",
                        token: tokenInfo.token,
                        expires: expirationTime,
                        ssl: false,
                        creationTime: creationTime,
                        resources: securedServices
                    }]
                });
                // store it client side
                if (_supports_local_storage()) {
                    // use local storage

                    window.localStorage.setItem(this._jsAPIIDManagerData, idString);
                } else {
                    // use a cookie
                    dojo.cookie(this._jsAPIIDManagerData, idString, { expires: 1 });
                }
                this._loadCredentials();
        
      });
      
               
        }
    
     function _supports_local_storage() {
            try {
                return "localStorage" in window && window["localStorage"] !== null;
            } catch (e) {
                return false;
            }
        }

        function _loadCredentials() {

            var idJson, idObject;
            if (this._supports_local_storage()) {
                // read from local storage
                idJson = window.localStorage.getItem(this._jsAPIIDManagerData);
            } else {
                // read from a cookie
                idJson = dojo.cookie(this._jsAPIIDManagerData);
            }
            if (idJson && idJson != "null" && idJson.length > 4) {
                idObject = dojo.fromJson(idJson);
                esri.id.initialize(idObject);
            }
        }
        
    
    dojo.addOnLoad(init);


      var i18n;
      dojo.ready(function(){

      
        i18n = dojo.i18n.getLocalization("esriTemplate","template");
        var  defaults = {
        //The ID for the map from ArcGIS.com
        webmap: "mywebmapid",
        //Modify this to point to your sharing service URL if you are using the portal
        sharingurl: null,//for example: "http://www.arcgis.com",
        //The id for the web mapping application item that contains configuration info - in most
        ////When editing you need to specify a proxyurl (see below) if the service is on a different domain
        //Specify a proxy url if you will be editing, using the elevation profile or have secure services or web maps that are not shared with everyone.
        proxyurl: "",
        //cases this will be null.
        appid: "",
        //set to true to display the title
        displaytitle: true,
        //Enter a title, if no title is specified, the webmap's title is used.
        title: "",
        //Enter a description for the application. This description will appear in the left pane
        //if no description is entered the webmap description will be used.
        description: "",
        //specify an owner for the app - used by the print option. The default value will be the web map's owner
        owner: '',
        //Specify a color theme for the app. Valid options are gray,blue,purple,green and orange
        theme: 'gray',
        //Optional tools - set to false to hide the tool
        //set to false to hide the zoom slider on the map
        displayslider: true,
        displaymeasure: true,
        displaybasemaps: true,
        displayoverviewmap: true,
        displayeditor: true,
        displaylegend: true,
        displaysearch: true,
        displaylayerlist: true,
        displaybookmarks: true,
        displaydetails: true,
        displaytimeslider: true,
        displayprint: true,
        
        displayelevation: false,
        //This option is used when the elevation chart is displayed to control what is displayed when users mouse over or touch the chart. When true, elevation gain/loss will be shown from the first location to the location under the cursor/finger.
        showelevationdifference: false,
        displayscalebar: true,
        displayshare: true,
        //Set to true to display the left panel on startup. The left panel can contain the legend, details and editor. Set to true to
        //hide left panel on initial startup. 2
        leftPanelVisibility: true,
        //If the webmap uses Bing Maps data, you will need to provide your Bing Maps Key
        bingmapskey: commonConfig.bingMapsKey,
        //specify a group in ArcGIS.com that contains the basemaps to display in the basemap gallery
        //example: title:'ArcGIS Online Basemaps' , owner:esri
        basemapgroup: {
          title: null,
          owner: null
        },
        //Enter the URL's to the geometry service, print task and geocode service. 
        helperServices: commonConfig.helperServices,
        //Set the label in the nls file for your browsers language
        printlayouts: [{
          layout: 'Letter ANSI A Landscape',
          label: i18n.tools.print.layouts.label1,
          format: 'PDF'
        }, {
          layout: 'Letter ANSI A Portrait',
          label: i18n.tools.print.layouts.label2,
          format: 'PDF'
        }, {
          layout: 'Letter ANSI A Landscape',
          label: i18n.tools.print.layouts.label3,
          format: 'PNG32'
        }, {
          layout: 'Letter ANSI A Portrait',
          label: i18n.tools.print.layouts.label4,
          format: 'PNG32'
        }],
        printlayout: false,
        printformat: "PNG32",
        //Specify the geocoder options. By default uses the geocoder widget with the default locators. If you specify a url value then that locator will be used.
        placefinder: {
          "url": "",
          "countryCode":"",
          "currentExtent":false,
          "placeholder": "",
          "singlelinefieldname":""
        },
        
        link1: {
          url: '',
          text: ''
        },
        link2: {
          url: '',
          text: ''
        },
        //specify the width of the panel that holds the editor, legend, details
        leftpanewidth: 228,
        //Restrict the map's extent to the initial extent of the web map. When true users
        //will not be able to pan/zoom outside the initial extent.
        constrainmapextent: false,
        //Provide an image and url for a logo that will be displayed as a clickable image
        //in the lower right corner of the map. If nothing is specified then the esri logo will appear.
        customlogo: {
          image: '',
          link: ''
        },
        //embed = true means the margins will be collapsed to just include the map no title or links
        embed: false
      };
        
        var app = new utilities.App(defaults);
        app.init().then(function(options){
            initMap(options);
        });

      });

    </script>







The could for the token generation was originally posted here:
http://forums.arcgis.com/threads/73298-Possible-to-hard-code-credentials?highlight=token

and the rest of the code you see is from the basic viewer
0 Kudos
21 Replies
ScottGrace
New Contributor III
ok, let's eliminate your esri.request code block for right now and just try copying and pasting the token into the following part of the code as a string.  do the same for your userId as well.  The expires property is a integer and not a string.

var token = {
"server": "http://www.arcgis.com/sharing/rest",
"userId": "USERID",
"token": "TOKEN",
"ssl": false,
"expires": 7200
};


that seemed to work... another issue i seem to have it that the file that my web map uses as a layer isnt being loaded. What is wrong with my esri.request, getting the token?
0 Kudos
ScottGrace
New Contributor III
Also, how did you set up the application on ArcGIS.com.  Did you create it as a "web application" or did you choose mobile, desktop, or application?  I set mine up as a Web Application with the "Ready to use" option and the API set to "Javascript".


this is how mine looks:

App ID:***********
App Secret:********
App Type:browser
Redirect URI's:**URL from properties*****


Properties
URL
*****
Code Attachment
None
Purpose Ready To Use
API JavaScript
Usage Credits Used
Shared with  Organization
0 Kudos
IanKramer3
New Contributor III
I'll play around with esri.request code you sent.  I am implementing my authentication in .NET, so I wasn't going to use the esri.request method, but it should work and now I am curious about why it is not working.

What kind of file are you trying to reference from your web map?
0 Kudos
ScottGrace
New Contributor III
I'll play around with esri.request code you sent.  I am implementing my authentication in .NET, so I wasn't going to use the esri.request method, but it should work and now I am curious about why it is not working.

What kind of file are you trying to reference from your web map?


the application references a kml file with points which is displayed when i open the application on AGOL itself.
0 Kudos
ScottGrace
New Contributor III
I'll play around with esri.request code you sent.  I am implementing my authentication in .NET, so I wasn't going to use the esri.request method, but it should work and now I am curious about why it is not working.

What kind of file are you trying to reference from your web map?


ive been playing with the eari.request all day...i cant imagine why it wouldnt work...is there another way to make an rest request?
0 Kudos
IanKramer3
New Contributor III
Actually, I see the issue.  You need to move this code inside your tokenObtained(response) function.  You need to get back the token before you create the web map.  In the code you supplied, it sends the request and then gets the webmap before the token is returned.  I tested your code and it works if you do that.

---------------------------------------
function tokenObtained(response) {
blah, blah, blah

var token = {
"server": "http://www.arcgis.com/sharing/rest",
"userId": userId,
"token": tokenStr,
"ssl": false,
"expires": expireStr
};

kernel.id.registerToken(token);

..CODE TO LOAD WEBMAP
}
0 Kudos
ScottGrace
New Contributor III
Actually, I see the issue.  You need to move this code inside your tokenObtained(response) function.  You need to get back the token before you create the web map.  In the code you supplied, it sends the request and then gets the webmap before the token is returned.  I tested your code and it works if you do that.

---------------------------------------
function tokenObtained(response) {
blah, blah, blah

var token = {
"server": "http://www.arcgis.com/sharing/rest",
"userId": userId,
"token": tokenStr,
"ssl": false,
"expires": expireStr
};

kernel.id.registerToken(token);

..CODE TO LOAD WEBMAP
}





Ohhhhhh, i see that makes sense. do you know why my kml file isnt working? its about 8 MB in size...could that be why it is running out?

Here is my log file dump from the chrome inspector:

XHR finished loading: "https://www.arcgis.com/sharing/oauth2/token?&client_id=*****&client_secret=****&grant_type=client_cr...". init.js:15
XHR finished loading: "http://www.arcgis.com/sharing/rest/content/items/****?f=json". init.js:15
Error {code: 403, messageCode: "GWM_0003", message: "You do not have permissions to access this resource or perform this operation.", details: Array[0], log: undefined�?�}
init.js:15
XHR finished loading: "http://www.arcgis.com/sharing/rest/content/items/****....". init.js:15
XHR finished loading: "http://www.arcgis.com/sharing/rest/content/items/****....". init.js:15
Resource interpreted as Script but transferred with MIME type text/plain: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer?f=json&callback=dojo...". init.js:34
XMLHttpRequest cannot load http://static.arcgis.com/attribution/World_Topo_Map?f=json. Origin http://localhost is not allowed by Access-Control-Allow-Origin. index_ian.html:1
_577 {stack: "Error: Unable to load http://static.arcgis.com/att�?�._3f3 (http://js.arcgis.com/3.6/init.js:15:99959)", message: "Unable to load http://static.arcgis.com/attribution/World_Topo_Map?f=json status: 0", response: Object, status: 0, responseText: ""�?�}
init.js:15
Resource interpreted as Script but transferred with MIME type text/plain: "http://utility.arcgis.com/sharing/kml?url=**my_AGOL_portal**&callback=dojo.io.script.jsonp_dojoIoScr...". init.js:34
dojo.io.script error
Error {code: 400, message: "File not found. Wrong url or out of memory.", details: Array[0], log: undefined, httpCode: 400}
init.js:34
XMLHttpRequest cannot load https://services.arcgisonline.com/ArcGIS/rest/info?f=json. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
0 Kudos
IanKramer3
New Contributor III
I am not sure about this one. It looks like you are getting a CORS error, basically your web server is not registered/allowed to access services.arcgisonline.com (its a security thing on their end), where I guess they are storing a copy of your KML file.  I have run into this error before with esri.request when trying to pull services from this server and basically I used a proxy to get around it (Esri recommends this).  However, since your KML is hosted on ArcGIS.com, I don't believe there is a proxy property for a Map object.  However there are a couple of workarounds that you may try:

#1 - Set up a proxy on your local web server following these: instructions: https://developers.arcgis.com/en/javascript/jshelp/ags_proxy.html

Then in your code towards the top, try using this:
esri.config.defaults.io.proxyUrl = "http://<INSERT SERVER ADDRESS HERE>/proxy/proxy.ashx";

They may force the communication for the KML file through the proxy.  I have no idea if this will work, but may be worth a try.

#2 - Load your KML on a web server or I see a lot of people using Dropbox now.  Then add your KML to your web map as a URL link and not a local file.

#3 - Load your KML into your web map in your JS app.  Check out this sample: https://developers.arcgis.com/en/javascript/jssamples/layers_kml.html

I hope one of these work for you.  You may also want to post that error on the forums as a separate thread.
0 Kudos
IanKramer3
New Contributor III
So it looks like this may be a limitation of JS.  I would implement it through the URL method.

http://forums.arcgis.com/threads/78003-Adding-KML-file-in-map-control-by-JavaScript-API?highlight=km...

Good Luck!
0 Kudos
ScottGrace
New Contributor III
So it looks like this may be a limitation of JS.  I would implement it through the URL method.

http://forums.arcgis.com/threads/78003-Adding-KML-file-in-map-control-by-JavaScript-API?highlight=km...

Good Luck!


I dont mean to beat a dead horse, but when i implement your solution on the basicviewer web application i am unable to see the legend, is there a way to make that visible? for the record it does show up when i sign on with my credentials.
0 Kudos