Access protected feature service with the Maps SDK

311
2
09-06-2023 03:57 AM
Labels (2)
BerendVeldkamp
Occasional Contributor II

I'm trying to access a protected feature service using the Maps SDK version 200.2, and would like to use an application login to do so.

 

My basic flow so far is this:

 

AuthenticationManager.Current.ChallengeHandler = new AppChallengeHandler();
      
var table = new ServiceFeatureTable(new Uri("https://example.com/arcgis/rest/services/Test/FeatureServer/0"));
await table.LoadAsync();

 

and

 

internal class AppChallengeHandler : IChallengeHandler
{
    public async Task<Credential> CreateCredentialAsync(CredentialRequestInfo requestInfo)
    {
        var challengeRequest = new CredentialRequestInfo
        {
            GenerateTokenOptions = new GenerateTokenOptions
            {
                TokenAuthenticationType = TokenAuthenticationType.OAuthClientCredentials,
            },
            ServiceUri = new Uri("https://example.com/portal"),
        };

        var serverInfo = AuthenticationManager.Current.FindServerInfo(
            new Uri("https://example.com/arcgis/rest"));
        serverInfo.OAuthClientInfo = new OAuthClientInfo(
            CLIENTID,
            new Uri("https://example.com"),
            CLIENTSECRET);
        serverInfo.TokenAuthenticationType = TokenAuthenticationType.OAuthClientCredentials;

        var creds = await AuthenticationManager.Current.GetCredentialAsync(challengeRequest, false);
        if (creds == null)
        {
            throw new Exception("Not authorized");
        }

        return creds;
    }
}

 

 

The call to LoadAsync triggers CreateCredentialsAsync, at which time a serverInfo object for the service is added to the AuthenticationManager.

However, the code just stops at GetCredentialsAsync, no exception, nothing in the output window of Visual Studio, no request to be seen in Fiddler.

Does anyone know how to do this?

0 Kudos
2 Replies
MichaelBranscomb
Esri Frequent Contributor

Have you tried Method GenerateCredentialAsync (arcgis.com) rather than Method GetCredentialAsync (arcgis.com)

I wonder if it never returns because it's stuck in a loop (Get will raise the Challenge, which will call Get, etc)?

0 Kudos
BerendVeldkamp
Occasional Contributor II

Thanks,

I replaced that line with

var creds = await AuthenticationManager.Current.GenerateCredentialAsync(
    new Uri("https://example.com/portal"), 
    challengeRequest.GenerateTokenOptions);

 

But now the program throws an exception 'OAuth-Client-id must be set before trying to generate an OAuth token'.

I think this is because the runtime is trying to lookup a serverInfo for the /portal URL rather than /arcgis. After adding a new serverinfo for /portal with the same clientid and secret to the AuthenticationManager, GenerateCredentials works, but it returns a credentials object for /portal, not /arcgis.

I also tried to return a new Credentials object for the correct /arcgis URl, but that doesn't seem to be accepted either.

//return creds;
return new OAuthTokenCredential(new Uri("https://example.com/arcgis/rest"), creds.Token)
{
    ExpirationDate = creds.ExpirationDate,
    GenerateTokenOptions = creds.GenerateTokenOptions
};

 

My CreateCredentialAsync method is called three times, before finally giving up.

0 Kudos