2

Our organization is hosting secured ArcGIS Server geodata and map servers (token based). The services are shared on ArcGIS Online, where specific AGOL users in a group are allowed access.

Now I want to access the services from an ArcMap add-in. The idea is for users to provide their AGOL credentials in ArcMap for permission to the service. Code like this to add a layer to the map works fine:

  IPropertySet propertySet = new PropertySetClass();
  propertySet.SetProperty("url", url);

  IAGSServerConnectionName AGSServerConnectionName = new AGSServerConnectionName();
  AGSServerConnectionName.ConnectionProperties = propertySet;

  IAGSServerObjectName AGSServerObjectName = new AGSServerObjectName();
  AGSServerObjectName.Name = serverName;
  AGSServerObjectName.Type = "MapServer";
  AGSServerObjectName.AGSServerConnectionName = AGSServerConnectionName;

  ILayerFactory factory = new MapServerLayerFactory() as ILayerFactory;
  IEnumLayer enumLayer = factory.Create(AGSServerObjectName);
  ILayer layer = enumLayer.Next();

  map.AddLayer(layer);

The ILayerFactory.Create() call even pops up the AGOL login screen if the user has not already logged in to AGOL.

Now my problem is that I need to use the geodata server to create a replica and extract data. The following code to get an IGeoDataServer works fine directly against our secured ArcGIS Server, using the necessary user and password in the connection properties. In Fiddler I can see that ArcObjects is requesting a token and then using that in subsequent calls.

protected IGeoDataServer2 InitGeoDataServerFromInternetServer(string url, string serviceName)
{

  // example url
  //url = @"http://utility.arcgis.com/usrsvcs/servers/04225973dd364b849a23915db2293d72/rest/services

  IGeoDataServer2 geoDataServer = null;

  // Create a property set for connection properties.
  IPropertySet propertySet = new PropertySetClass();
  propertySet.SetProperty("URL", url);
  //propertySet.SetProperty("user", "XXXXXX");
  //propertySet.SetProperty("password", "XXXXXXXXXXXXX");

  using (ESRI.ArcGIS.ADF.ComReleaser comReleaser = new ESRI.ArcGIS.ADF.ComReleaser())
  {

    // Connect to the server.
    Type factoryType = Type.GetTypeFromProgID("esriGISClient.AGSServerConnectionFactory");
    IAGSServerConnectionFactory agsServerConnectionFactory = (IAGSServerConnectionFactory)Activator.CreateInstance(factoryType);
    comReleaser.ManageLifetime(agsServerConnectionFactory);
    IAGSServerConnection agsServerConnection = agsServerConnectionFactory.Open(propertySet, 0);

    // Get an enumerator for the server object types.
    IAGSEnumServerObjectName enumServerObjectName = agsServerConnection.ServerObjectNames;
    enumServerObjectName.Reset();

    // Iterate through the objects to locate the GeoData service.
    IAGSServerObjectName serverObjectName = null;
    while ((serverObjectName = enumServerObjectName.Next()) != null)
    {
      if (serverObjectName.Type == "GeoDataServer" && (serverObjectName.Name.ToLower() == serviceName.ToLower()))
      {
        IName name = (IName)serverObjectName;
        geoDataServer = (IGeoDataServer2)name.Open();
        break;
      }
    }

    // Return the geo dataserver.
    return geoDataServer;

  }

}

However, when I run it against the desired AGOL service URL (and without the user/password property settings), I was hoping ArcObjects would again pop the AGOL sign-in dialog and take care of handling the tokens as necessary. But that isn't happening. Instead it fails when accessing the IAGSServerConnection.ServerObjectsName with

{"Access to this resource is forbidden, regardless of authorization."}

Fiddler shows that ArcObjects is calling the services catalog to get authInfo, for example

{"currentVersion":10.22,"owningSystemUrl":"http://www.arcgis.com","authInfo":{"tokenServicesUrl":"https://www.arcgis.com/sharing/rest/generateToken","isTokenBasedSecurity":true}}

But when it calls generateToken, the response is

{"error":{"code":403,"messageCode":"GWM_0004","message":"This request needs to be made over https.","details":[]}}

Note the same thing happens if I try similar code to get IMapServer.

So my question, is there a way to get IMapServer and IGeoDataServer from a secured ArcGIS service that is shared on ArcGIS Online? My hunch is it's not an ArcObjects problem but something with the security implementation. Not sure where to look though.

closed as off-topic by PolyGeo Sep 16 '16 at 7:56

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This problem cannot or can no longer be reproduced. Changes to the system or to the asker's circumstances may have rendered the question obsolete, or the question does not include a procedure to enable potential answerers to reproduce the same symptoms. Such questions are off-topic as they are unlikely to help future readers, but editing them to include more details can lead to re-opening." – PolyGeo
If this question can be reworded to fit the rules in the help center, please edit the question.

  • Did you try using ArcGISSingleSignon ? desktop.arcgis.com/en/arcobjects/latest/net/… – Kirk Kuykendall Apr 7 '16 at 16:22
  • Yes, thanks, I have tried ArcGISSingleSignon and can successfully log on and get the token with GetToken(). I can also get the token with GetCurrentToken() if the user has already logged on via the ArcMap interface. But I don't see any way to use the token. It appears via Fiddler that ArcObjects is attempting to figure out what is required as far as authentication and automatically use the token, but something is not right. So now I'm thinking there is something wrong with the way we have ArcGIS Server and/or the Web Adaptor configured. I'll be talking with our admin person more today. – John C Apr 11 '16 at 13:58