AuthenticationManager.GetCredentialAsync does not throw Exception

1663
6
07-14-2017 09:44 AM
deleted-user-Ohz6rwd1kavx
New Contributor III

Hi All,

We are using this method to generated a Credential before calling GeodatabaseSyncTask.CreateAsync().

AuthenticationManager.GetCredentialAsync(CredentialRequestInfo credentialRequestInfo, bool retry)

The way this works is that the default challenge dialog appears prompting user for userid/pwd. This works fine if the url is accessible, but in situation where the url is not accessible (e.g. internal url and device is outside the firewall), the method does not throw an exception.

Is there a way using this method (or similar from the SDK) to know that the url isn't accessible, e.g. via a thrown Exception?

Currently, all the user sees is a message in the default challenge dialog: "Previous error: An error occurred while sending the request". In VS if I enable "Compile with .NET Native tool chain" I can get a little bit more information, but I am looking for a clean solution for this.

Any guidance appreciated.

Thanks!

-Cory

0 Kudos
6 Replies
JoeHershman
MVP Regular Contributor

I usually send a WebRequest to the Url and see if I get a response to confirm connectivity prior to calling the method when this is a concern.

Thanks,
-Joe
0 Kudos
deleted-user-Ohz6rwd1kavx
New Contributor III

Hi Joe,

Thanks. I added this based on your suggestion. Working so far.

The ArcGIS Runtime SDK sends a Get using this url when I call Authentication.GetCredentialAsync, so that's the url template I ended up using for my sniff test.

"https://{0}/arcgis/rest/info?f=json"

-Cory

0 Kudos
deleted-user-Ohz6rwd1kavx
New Contributor III

To clarify, the SDK sends the above request as the challenge dialog appears. This is before user has entered their credentials or clicked Ok on the dialog. After user clicks OK -- logically --,  a send request is sent to the tokens url (https://{0}/arcgis/tokens/). In my fail scenario, both of these requests are failing, but I wasn't able to catch an exception from either.

0 Kudos
JoeHershman
MVP Regular Contributor

One thing I find less than optimal is the way that await/async handles exceptions in regards to sending them back to the calling methods.  Perhaps that is just my lack of understanding on how they are meant to work.  But I think this might be a general issue because it seems to me that APIs I use don't always throw a meaningful (or any) exception back to the caller.  Just my observation.  I'll be honest, I have gotten to think the simplicity of async/await often can results in worse code.

Thanks,
-Joe
0 Kudos
JenniferNery
Esri Regular Contributor

You'll need to await GenerateCredential if you want to programmatically create the credential and get an exception thrown for bad username/password. The following code should give you an ArcGISWebException `You are not authorized to access this information`.

try
{
    var credential = await AuthenticationManager.Current.GenerateCredentialAsync(new Uri("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Wildfire_secure_ac/FeatureServer"),
        "user1",
        "bad_password"); // u/p for this service is user1/user1;   
        
}
catch(Exception ex)
{
    MessageBox.Show(ex.Message, ex.GetType().Name);
}
0 Kudos
deleted-user-Ohz6rwd1kavx
New Contributor III

Hi Jennifer,

Thanks for your reply.

I'm using a different method (see code below). This is the signature which shows the (system?) challenge dialog which prompts the user for user/pwd.

Also, to clarify, the issue occurs before the user enters any information. 

Idea: I think that the Esri method is not throwing an exception in situation where url is not accessible (either that, or I'm missing something). Would be nice if an exception were thrown. 

Question: Anyone else seeing issue where a _deployed_ UWP app cannot access this url when url is internal? Works fine in browser on deployment machine. Also works fine in UWP app on development machine.

"https://{0}/arcgis/rest/info?f=json"

We are still looking for root cause here. Any ideas appreciated.

            GenerateTokenOptions tokenOptions = new GenerateTokenOptions()
            {
                TokenAuthenticationType = TokenAuthenticationType.ArcGISToken,
            };
            CredentialRequestInfo requestInfo = new CredentialRequestInfo()
            {
                AuthenticationType = AuthenticationType.Token,
                GenerateTokenOptions = tokenOptions,
                ServiceUri = _syncUri
            };
           
            Credential credential = await AuthenticationManager.Current.GetCredentialAsync(requestInfo, false);

Thanks,

-Cory

0 Kudos