Download: SecurityManager.zip Introduction The Esri Identity Manager control is ideal for scenarios where you need a login control for prompting your users for credentials. The control is fully responsible for generating a valid token from your Identity Provider and associating that token with your resources. This is perfect because all the complexities around security are handled by the Esri control allowing developers to be only concerned with the functionality they need to implement. However, if your application needs to access services from different domains then you need to develop a proxy page or use CORS if supported by the browser. For further details refer to: https://developers.arcgis.com/en/javascript/jsapi/identitymanager-amd.html There are also situations where you want to build your own Javascript application and seamlessly pass through your credentials at run-time and avoid the prompt dialog. Because most people would develop a proxy page to solve these problems I’ve decided to attempt solving it with just JavaScript. This can be useful in the following scenarios: 1 – You don’t have time to develop a proper and secure proxy page to integrate with your solution and with the ArcGIS stack. 2 – You have to provide access to your secure resources to applications that are out of your control and that are being implemented by developers that have no knowledge of ArcGIS and how to authenticate against it. 3 – You can’t provide the proxy page to these organizations because you cannot guarantee that it will be properly used/not compromised. The javascript library in this post performs several functions including:
|
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10"/> <title>Consume secured web map from Portal for ArcGIS</title> <link rel="stylesheet" href="https://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/dojo/dijit/themes/claro/claro.css"> <link rel="stylesheet" href="https://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/esri/css/esri.css"> <link rel="stylesheet" href="https://developers.arcgis.com/en/javascript/samples/ags_createwebmapid/css/layout.css"> <script> var dojoConfig = { parseOnLoad: true }; </script> <script src="https://serverapi.arcgisonline.com/jsapi/arcgis/3.5/"></script> <script src="Scripts/jquery-2.0.0.min.js"></script> <script src="Scripts/security-1.0.2.min.js"></script> <script> dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("esri.map"); dojo.require("esri.dijit.Legend"); dojo.require("esri.dijit.Scalebar"); var map; var resources = ["https://www.arcgis.com/sharing/rest/content/items/6d4047a85f674545a66666eaea44064f"]; var webmapid = "6d4047a85f674545a66666eaea44064f"; // PLEASE HIDE THE CREDENTIALS. THEY ARE SHOWN HERE FOR EASY UNDERSTANDING var credentials = { "userid": "jose", "username": "jose", "password": "pass1", "validity": 60 }; // validity is in minutes (>=1) function ready() { /// Manages the identity of the application by leveraging the Esri IdentityManager behind the scenes. /// @resources: Secured resources to be used. E.g.: /// Portal: ["https://www.arcgis.com/sharing/rest/content/items/0f6845e6e6bc4a84bee008a71c857df3"] /// Server: ["https://mydomain/arcgis/rest/services/MyMap/MapServer","https://mydomain/arcgis/rest/services/MyMap2/MapServer"] /// @credentials: Credentials (e.g. { "userid": "jose", "username": "jose", "password": "jose", "validity": 60 } ). /// Note that validity cannot be inferior to 1. /// @cache: Default is true. When set to true the class optimizes the performance of the application, reusing and negotiating /// new tokens only when required (e.g. when the token is expiring). /// If set to false, whenever the application restarts (or this method is called again) the class clears the cache /// before proceeding. /// @completed: The execution complete event handler. Security.ManageResources(resources, credentials, false, function () // change the cache to true when happy with the settings { // to avoid reusing older tokens // YOUR CODE HERE initializeApp(); }); }; function initializeApp() { var request = esri.arcgis.utils.createMap(webmapid, "map"); request.then(function (response) { dojo.byId("title").innerHTML = response.itemInfo.item.title; dojo.byId("subtitle").innerHTML = response.itemInfo.item.snippet; map = response.map; // get the layers that will display in the legend var layers = esri.arcgis.utils.getLegendLayers(response); console.log(layers); if (map.loaded) { initMap(layers); } else { dojo.connect(map, "onLoad", function () { initMap(layers); }); } }, function (error) { console.log("Map creation failed: ", dojo.toJson(error)); }); } function initMap(layers) { //add a scalebar var scalebar = new esri.dijit.Scalebar({ map: map, scalebarUnit: "english" }); //add a legend var legendDijit = new esri.dijit.Legend({ map: map, layerInfos: layers }, "legend"); legendDijit.startup(); } dojo.ready(ready); </script> </head> <body class="claro"> <div id="mainWindow" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;"> <div id="header" class="shadow roundedCorners" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'"> <div id="title"></div> <div id="subtitle"></div> </div> <div id="map" class="roundedCorners shadow" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div> <div id="rightPane" class="roundedCorners shadow" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'right'" > <div id="legend"></div> </div> </div> </body> </html>
ArcGIS for Server Example (Federated or not)
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10"/> <title>Consume secured services from ArcGIS for Server</title> <link rel="stylesheet" href="//serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/dojo/dijit/themes/tundra/tundra.css"> <link rel="stylesheet" href="//serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/esri/css/esri.css"> <style type="text/css"> html, body { height: 100%; width: 100%; margin:0; padding:0; } </style> <script>var dojoConfig = { parseOnLoad: true };</script> <script src="Scripts/jquery-2.0.0.min.js"></script> <script src="https://serverapi.arcgisonline.com/jsapi/arcgis/3.5/"></script> <script src="Scripts/security-1.0.2.min.js"></script> <script> dojo.require("dijit.layout.BorderContainer"); dojo.require("dijit.layout.ContentPane"); dojo.require("esri.map"); dojo.require("esri.layers.FeatureLayer"); var map; var resources = ["https://sampleserver6.arcgisonline.com/arcgis/rest/services/SaveTheBay/FeatureServer/0", "https://sampleserver6.arcgisonline.com/arcgis/rest/services/SaveTheBay/FeatureServer/1"]; // PLEASE HIDE THE CREDENTIALS. THEY ARE SHOWN HERE FOR EASY UNDERSTANDING var credentials = { "userid": "user1", "username": "user1", "password": "user1", "validity": 60 }; // >= 1 minutes. function ready() { /// Manages the identity of the application by leveraging the Esri IdentityManager behind the scenes. /// @resources: Secured resources to be used. E.g.: /// Portal: ["https://www.arcgis.com/sharing/rest/content/items/0f6845e6e6bc4a84bee008a71c857df3"] /// Server: ["https://mydomain/arcgis/rest/services/MyMap/MapServer","https://mydomain/arcgis/rest/services/MyMap2/MapServer"] /// @credentials: Credentials (e.g. { "userid": "jose", "username": "jose", "password": "jose", "validity": 60 } ). /// Note that validity cannot be inferior to 1. /// @cache: Default is true. When set to true the class optimizes the performance of the application, reusing and negotiating /// new tokens only when required (e.g. when the token is expiring). /// If set to false, whenever the application restarts (or this method is called again) the class clears the cache /// before proceeding. /// @completed: The execution complete event handler. Security.ManageResources(resources, credentials, false, function () // change the cache to true when happy with the settings { // to avoid reusing older tokens // YOUR CODE HERE initializeApp(); }); }; function initializeApp() { //map = new esri.Map("map"); map = new esri.Map("map", { basemap: "topo", center: [-107.394, 37.563], zoom: 9 }); //var layer = new esri.layers.ArcGISDynamicMapServiceLayer(resources[0]); //map.addLayer(layer); var layer1 = new esri.layers.FeatureLayer(resources[0], { mode: esri.layers.FeatureLayer.MODE_ONDEMAND, outFields: ["*"] }); map.addLayer(layer1); var layer2 = new esri.layers.FeatureLayer(resources[1], { mode: esri.layers.FeatureLayer.MODE_ONDEMAND, outFields: ["*"] }); map.addLayer(layer2); // Shows how to use other features of the Security Utility // //if (map.loaded) OtherExamples(); //else // dojo.connect(map, "onLoad", function () { OtherExamples(); }); //function OtherExamples() //{ // Security.RemoveResources(["https://sampleserver6.arcgisonline.com/arcgis/rest/services/SaveTheBay/FeatureServer/0"], function () // { // Security.AddResources(["https://sampleserver6.arcgisonline.com/arcgis/rest/services/SaveTheBay/FeatureServer/0"], function () // { // var layer2 = new esri.layers.FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/SaveTheBay/FeatureServer/1", // { mode: esri.layers.FeatureLayer.MODE_ONDEMAND, outFields: ["*"] }); // map.addLayer(layer2); // }); // }); //} }; dojo.ready(ready); </script> </head> <body class="tundra"> <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline', gutters:false" style="position:relative;width:100%;height:100%;"> <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div> </div> </body> </html>