I am building a web app in a low code platform (Mendix). I am connecting the web app with ArcGIS online resources via the ArcGIS JavaScript API v4.19, which all goes pretty smoothely.
The challenge arises when I want to load specific secured ArcGIS online content via the ArcGIS JavaScript API, specifically from some FeatureLayers which are secured. I looked into the documentation and it seems the best way forward would be a so-called 'application login'. For this I want to setup an OAuth application login based on CLient ID and Client Secret. With these two I can get a valid token via AOuth and use that token to access the content by feeding the token to the IdentityManager via the JavaScript API.
This is were it goes wrong currently, I can't seem to figure out where to make it explicit on the ArcGIS online side that this specific secured FeatureLayer can be accessed via this application login, hence currently I am getting errors that the valid token and app id don't have access to the resource, being the end-point of the secured FeatureLayer.
Does anybody know how to associate a secured FeatureLayer in ArcGIS online to a application login?
EDIT 10-6-2021: Added code sample
After succesfully retrieving a valid token on the server side based on client id and client secret I use the client ID (=AppID) and token in the ArcGIS JavaScript API like below:
const token = {
server: "http://www.arcgis.com",
userId: <AppID>,
token:
<valid token retrieved via OAuth generateToken request,
ssl: true,
expires: 7200
};
IdentityManager.registerToken(token);
Only implementing this gives me an error whilst trying to access the secured feature layer:
identity-manager:not-authorized. "You are currently signed in as: AppID. You do not have access to this resource: https://server/someid/arcgis/rest/services/somefeatureserver/FeatureServer/0
I also read that sometimes below could be needed so added as well:
const idString = JSON.stringify(IdentityManager.toJSON());
console.debug("idString: " + idString);
IdentityManager.initialize(idString);
This resolves the error but makes a login popup appear again.
The layer is afterwards declared like below:
const layer = new FeatureLayer({
// URL to the service
url: layerObj.layerURLStatic
definitionExpression: queryDefinition,
featureReduction: clusterConfig && { type: "cluster" },
popupTemplate: {
title: "{" + inAttributeTitle + "}",
content: [
{
type: "fields", // FieldsContentElement
fieldInfos
}
],
actions: [
{
title: props.intButtonLabel,
id: btnId,
className: props.intButtonClass + intButtonIconClass,
type: "button"
}
]
},
outFields: ["*"]
});
webMap.add(layer);
Here is a snippet to generate the token and then register it with IdentityManager:
IdentityManager = require('esri/identity/IdentityManager')
function login(user, password){
var serverInfo = {
"server": "https://www.arcgis.com",
"tokenServiceUrl" : "https://www.arcgis.com/sharing/generateToken"
};
var userInfo = {
username : user,
password : password
}
IdentityManager.generateToken(serverInfo, userInfo).then(function (response){
response.server = serverInfo.server;
response.userId = user;
IdentityManager.registerToken(response);
});
}
I'm not sure how you are going to fit this in you app, but the sample should work if you paste it in your developer tools console when the app is running.
Also, it seems to me that userId property is for arcgis online username, not for appId.
As pointed out by Shaked, if you append '?token=[token_value]' int the layer URL you probably don't even need to register the token to query the layer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With