I'm having some pesky problems implementing some authentication for my JS App (which is hosted on an internal web server). I thought that I could follow the Application login workflow (create application in Portal, use OAuthInfo class with appId to authenticate user to my Portal and gain access to my app) to allow only specific users to access my application as long as I set the security (through Portal) of my Web Mapping Application item to one of my Portal security groups. Turns out it doesn't matter if the Web Mapping Application is shared with everyone or no one - if my JS web app has the appId, any user can login to my application.
So the only way (seemingly) to allow only some users access to my application is to restrict the _layers_ in my app to specific groups and use the IdentityManager class to challenge a user, etc. etc. I like how the API handles much of this workflow without much extra coding - if my app tries to add a restricted layer to the map (map.addLayers([restrictedLayer1, layer2]), the user is prompted to sign in. However, sometimes those restricted layers are not added until after a bunch of other stuff happens (dom parsing, widget instantiation, etc etc).
I would like to make sure the user has access to those secured layers before anything else happens, especially before my app gets to the point where it is trying to add those secured layers to the map. I don't know how to do this. What classes and methods should I use to challenge a user and determine if that user has access to a specific restricted layer? I tried using IdentityManager getCredential method, where the URL is my restricted layer endpoint, but that didn't work. Any suggestions?
Jay,
You can use esriRequest in a function that is the first to get called in your codes workflow by using dojo Ready to call your check authorization function and only after that do you call the main init function to defines the map, etc, etc.
Thanks Robert - do you have any examples of working code that implements this workflow that I might be able to look at? I'm having some difficulty with it.
Jay,
Sorry for the delay. Here is what I came up with that seems to work well.
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/> <title>Simple Map</title> <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/css/esri.css"> <link rel="stylesheet" href="https://js.arcgis.com/3.16/dijit/themes/claro/claro.css"> <style> html, body, #map { height: 100%; margin: 0; padding: 0; } </style> <script src="https://js.arcgis.com/3.16/"></script> <script> var map; require([ "esri/map", "esri/IdentityManager", "esri/layers/ArcGISDynamicMapServiceLayer", "dojo/domReady!" ], function(Map, esriId, ArcGISDynamicMapServiceLayer) { map = new Map("map", { basemap: "topo", //For full list of pre-defined basemaps, navigate to http://arcg.is/1JVo6Wd center: [-122.45, 37.75], // longitude, latitude zoom: 13 }); var cred = esriId.getCredential("http://mycomputer/arcgis/rest/services/mysecureservice/MapServer").then( function(result){ console.info(result); var secDynLyr = new ArcGISDynamicMapServiceLayer("http://mycomputer/arcgis/rest/services/mysecureservice/MapServer"); map.addLayer(secDynLyr); }, function(err){ console.info(err); } ); }); </script> </head> <body class="claro"> <div id="map"></div> </body> </html>
So what I found with this solution (which I had tried) was that esriId.getCredential will succeed as long as the user is a member of my Portal, and even if my member does NOT have access to the url endpoint passed into the function as a parameter. Are you not seeing this behavior when you try logging in with a user that doesn't have permission to your secured service? It doesn't make sense to me, but that is the behavior I am seeing....
Jay,
When you secured the map service in Manager did you have "Allow access to all users who are logged in" checked? Because I am not seeing what you are seeing and mine is working correctly and not adding the service if the user is not authorized. Now if the user is an admin that no matter what they will have access.
I use a federated / hosted Portal instance on top of my server, so I set the sharing through Portal, not through Manager. And the service is set to only provide access to members of a group, not all members of the Portal....
Jay,
A federated portal instance is outside my area of expertise so I would suggest a contact to tech support then.