Select to view content in your preferred language

Getting 401 (Unauthorized) accessing secured service with valid credentials

3116
3
Jump to solution
11-09-2018 02:36 AM
alehmann
Occasional Contributor

I'm trying to access a secured ArcGIS Server MapService that uses AD authentication. I can access the service in the browser on the device with the credentials provided by the customer. Yet I'm unable to load a map as I'm always getting the following exception:

System.Net.Http.HttpRequestException: 401 (Unauthorized)
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode () [0x0002a] in <f26106f7890945d7922088b4caacae4a>:0
at Esri.ArcGISRuntime.Internal.RequestRequiredHandler+<IssueRequestAndRespond>d__14.MoveNext () [0x005fd] in C:\daily_r\api_xam\dotnet\api\src\Esri.ArcGISRuntime\Esri.ArcGISRuntime.Shared\Internal\RequestRequiredHandler.cs:265
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <43dbbdc147f2482093d8409abb04c233>:0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <43dbbdc147f2482093d8409abb04c233>:0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <43dbbdc147f2482093d8409abb04c233>:0
at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <43dbbdc147f2482093d8409abb04c233>:0
at App4.MainPage+<InitMap>d__5.MoveNext () [0x00136] in C:\Users\<myuser>\source\repos\App4\App4\App4\MainPage.xaml.cs:56

The complete code is as follows:

using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Security;
using Esri.ArcGISRuntime.Xamarin.Forms;
using System;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace App4
{
    public partial class MainPage : ContentPage
    {

        static string ServerUrl = "https://<url to customer's arcgis server>";
        static string layerUrl = "https://<url to customer's arcgis server>/rest/services/<service>/MapServer";
        static string user = "<user>";
        static string pw = "<password>";

        public MainPage()
        {
            InitializeComponent();

            InitMap();
        }

        private async Task InitMap()
        {
            try
            {

                var mapView = new MapView();

                var authManager = Esri.ArcGISRuntime.Security.AuthenticationManager.Current;
                authManager.AddCredential(new ArcGISNetworkCredential()

                {

                    Credentials = new NetworkCredential(user, pw),

                    ServiceUri = new Uri(layerUrl)

                });
                authManager.RegisterServer(new ServerInfo { ServerUri = new Uri(ServerUrl) });

                var map = new Map();
                map.Basemap.BaseLayers.Add(new ArcGISMapImageLayer(new Uri(layerUrl)));

                mapView.Map = map;

                Content = mapView;
                await map.LoadAsync();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                await DisplayAlert("Error", ex.ToString(), "OK");
            }
        }

    }

}

This happens with Runtime SDK version 100.2, 100.2.1, 100.3 and 100.4. The app itself is the default Xamarin.Forms template in Visual Studio 2017 using shared code. I'm testing on Android at the moment - can't say if it happens on all platforms.

The code for authentication is taken basically 1:1 from Use the Authentication Manager—ArcGIS Runtime SDK for .NET | ArcGIS for Developers (HTTP (integrated Windows authentication) authorization)

The server is version 10.3.1, using web authentication in IIS with AD accounts.

If needed I'm able to provide the URL to the service along with valid credentials.

0 Kudos
1 Solution

Accepted Solutions
alehmann
Occasional Contributor

Okay, going at it with a fresh mind helped. It seems the problem lies in the HttpClient implementation. Using the native (Android) implementation leads to the described problem. Changing it to "managed" resolves this problem.

Is this a known problem? If so, I think it would be useful to mention it somewhere prominently as the native implementation is the default setting in VS2017.

View solution in original post

0 Kudos
3 Replies
alehmann
Occasional Contributor

Okay, going at it with a fresh mind helped. It seems the problem lies in the HttpClient implementation. Using the native (Android) implementation leads to the described problem. Changing it to "managed" resolves this problem.

Is this a known problem? If so, I think it would be useful to mention it somewhere prominently as the native implementation is the default setting in VS2017.

0 Kudos
dotMorten_esri
Esri Notable Contributor

Yes it's a known issue with the Android Http Handlers. They each have their pros and cons, and a lot of people are using the ModernHttpClient: GitHub - paulcbetts/ModernHttpClient: HttpClient implementations that use platform-native HTTP clien... 

After adding the NuGet you can set this up like this:

System.Environment.SetEnvironmentVariable("XA_HTTP_CLIENT_HANDLER_TYPE", "ModernHttpClient.NativeMessageHandler,ModernHttpClient");

(make sure you call this prior to making any HTTP Requests)

I thought this was already documented, but I can't find it either, so I'll follow up with our doc people.

0 Kudos
StevenMurray1
New Contributor

Hi there,

I am running into this same problem while testing in UWP. My Android application crashes completely while trying to load the map. This is with version 100.5.0 of the .Net SDK.

I am first trying to load the map service layer in my map using the default authentication challenger and no matter which credentials I put it, it returns 401 Unauthorized.

Any help would be appreciated,

Thanks

0 Kudos