GeodatabaseSyncTask + token

3721
14
Jump to solution
08-25-2015 02:19 AM
ArneDahlman
New Contributor III

Hi all!

Does any one know if it is possible to sync geodatabase using service that requires autentication (token)?

Generate geodatabase works fine with token, but when I try to sync my geodatabase back to server, it fails.

I am using a pregenerated long term token.

In fiddler I can se this response {"error":{"code":499,"message":"Token Required","details":[]}} after 401 challange,

I don't se any token in the post request, so I belive the problem is in my code or a bug in the .NET runtime.

My code:

var taskParameters = new SyncGeodatabaseParameters()

{

    RollbackOnFailure = false,

    SyncDirection = Esri.ArcGISRuntime.Tasks.Offline.SyncDirection.Upload

};

var gdbTask = new GeodatabaseSyncTask(uri);

gdbTask.Token = token; // pregenerated longterm token

GenerateGeodatabaseResult r = await gdbTask.SyncGeodatabaseAsync(taskParameters, gdb, syncCompleteCallback, null, new TimeSpan(0, 0, 3), progress, cancelToken);

I have tried this in both runtime 10.2.5 & 10.2.6.  (ArcGIS Server 10.22)

0 Kudos
1 Solution

Accepted Solutions
AnttiKajanus1
Regular Contributor II

Yes, that's possible. You have 2 ways to handle that. One is to include credentials to the application that are used in authentication or you can use a proxy. Read more from here​.

View solution in original post

0 Kudos
14 Replies
AnttiKajanus1
Regular Contributor II

Hi,

Synchronization should work with secured services. How are you generating the token and can you confirm that it's set correctly to the GeodatabaseSyncTask?

0 Kudos
ArneDahlman
New Contributor III

Thanks for your reply!

I have confirmed that I use exactly the samt token for both GenerateGeodatabaseAsync and SyncGeodatabaseAsync and that it is the same service beeing used in both cases. I can also conform that it is set on the GeodatabaseSyncTask object. It is working for GenerateGeodatabaseAsync, so the token used should be ok. It is a long term token generated on arcgis server manually.

Here is the url-decoded request-body for GenerateGeodatabaseAsync (createReplica) this is working as expected and I get my gdb. Here you can se the token in the request body:

f=json&layers=6, 5, 4, 3, 2, 1, 0, 9, 8, 7&layerQueries={"0":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"},"1":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"},"2":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"},"3":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"},"4":{"where":"ARENDEID=3029258 AND (HUINVENTERINGID=154 OR HUINVENTERINGID=-1)","queryOption":"useFilter"},"5":{"where":"ARENDEID=3029258 AND (HUINVENTERINGID=154 OR HUINVENTERINGID=-1)","queryOption":"useFilter"},"6":{"where":"ARENDEID=3029258 AND (HUINVENTERINGID=154 OR HUINVENTERINGID=-1)","queryOption":"useFilter"},"7":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"},"8":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"},"9":{"where":"ARENDEID=3029258 AND HUINVENTERINGID=154","queryOption":"useFilter"}}&geometryType=esriGeometryEnvelope&geometry={"xmin":-180000,"ymin":6080000,"xmax":1200000,"ymax":7690000}&transportType=esriTransportTypeUrl&returnAttachments=false&async=true&syncModel=perLayer&dataFormat=sqlite&clientTime=1440655554394&token=QLRmApTScQVLcvKrKMiz2a2QGdp_T9dj2W3wA14MqtJ2o54dE21i8WeZntrHHvMEv9Y2bPAhANqI0U0Hd8MIKA..

When I try to execute SyncGeodatabaseAsync (synchronizeReplica) with my map edits, there is no token parameter included in the request:

f=json&replicaID={345D9CE5-D7B3-4F28-AD1F-37D115E8AE60}&rollbackOnFailure=false&closeReplica=false&syncLayers=[{"id":6,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":5,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":4,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":3,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":2,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":1,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":0,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":9,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":8,"serverGen":1440655215837,"syncDirection":"bidirectional"}, {"id":7,"serverGen":1440655215837,"syncDirection":"bidirectional"}]&transportType=esriTransportTypeUrl&async=true&dataFormat=sqlite

0 Kudos
AnttiKajanus1
Regular Contributor II

Could you post a solution that reproduces this issue so I could have a look on it? You can also email it to me at akajanus-at-esri.com.

0 Kudos
ArneDahlman
New Contributor III

Here is a solution that reproduces the problem:

https://dl.dropboxusercontent.com/u/50166018/SyncTest.zip

0 Kudos
AnttiKajanus1
Regular Contributor II

It seems that I don't have access to the services.

Can you try to generate token in the fly using following code? It needs I'm using SignInChallengeHandler (from toolkit) for the authentication UI and using 24 hour token. I tested this against secured FeatureService in ArcGIS Online (at the moment I don't have server at hand) and it works without issues.

   // Register ChallengeHandler from Toolkit (can be downloaded from nuget or combiled from 

   // https://github.com/Esri/arcgis-toolkit-dotnet

   IdentityManager.Current.ChallengeHandler = new SignInChallengeHandler();

   // Request authentication against the portal, use 24h token

   ArcGISTokenCredential crd = await IdentityManager.Current.GetCredentialAsync(

   new CredentialRequestInfo { ServiceUri = _urlStr, GenerateTokenOptions = new GenerateTokenOptions() { TokenValidity = 1440 } },

   true) as ArcGISTokenCredential;

  _ServergeneratedLongtermToken = crd.Token;
;
0 Kudos
ArneDahlman
New Contributor III

When I use SignInChallengeHandler it's working.

In fiddler I can se that the token now is apended to the request url.

I did som more testing.

It is also working even if I dont use the token returned from the SignInChallengeHandler!

I run SignInChallengeHandler, but I ignore the generated token and asign gdbTask.Token to my original longterm token.

So, the conclusion must be that there is a bug here. SyncGeodatabaseAsync is ignoring the Token property.

The token is stored somewhere else.

0 Kudos
AnttiKajanus1
Regular Contributor II

IdentityManager stores the tokens and attaches it to the requests that goes to the registered servers. In this case it might be that task.Token gets ignored and overwritten by the IdentityManager or there might be bug how the token is attached to the request in the first place but finding that out needs a bit more digging.

Could you check that the token that gets attached to the requests is the same that is registered to the IdentityManager?

0 Kudos
ArneDahlman
New Contributor III

Yes, I it is the token from IdentityManager that gets attached to the request.

0 Kudos
AnttiKajanus1
Regular Contributor II

I have created bug for this issue. It seems that the Token is getting ignored but solution will work if used IdentityManager. What is your workflow that involves manually creating and storing tokens?

0 Kudos