2

How to pass DefaultCredentials in ASP.NET Core to the HttpClient?

It works fine when I run it locally in VisualStudio. The current user is authorized to request "www.mycompany.com". But as soon as I publish it to the IIS I get an 401 (Unauthorized) because HttpClient get the web-server-user (not authorized) in DefaultCredentials.

Windows-Authentification is active in VisualStudio and on IIS.

My c# code:

HttpClient Client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
Client.BaseAddress = new Uri("www.mycompany.com");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Client.DefaultRequestHeaders.Add("Application-Name", Assembly.GetExecutingAssembly().GetName().Name);

HttpResponseMessage response = Client.GetAsync("/classes").Result;

EDIT

I understand that locally it runs with current user, but I don't know how to authorize the Application Pool...

EDIT2

I didn't quite explain it correctly. I want to pass-trough the authentication from the local user to the HttpClient. Only local users are authorized to make a request

Eugen Kehl
  • 31
  • 1
  • 3
  • 1
    When you run it with Visual Studio, then you are running this with your current user. When you deploy to IIS, this is run with the application pool identity. You will need to either authorize the application pool identity with your target system, or change the user the application pool runs with. – poke Mar 22 '20 at 14:46
  • There are tons of key differences you should be aware of https://blog.lextudio.com/web-application-differences-in-visual-studio-and-iis-60fec7e311b3 – Lex Li Mar 22 '20 at 15:22
  • _“I want to pass-trough the authentication from the local user to the HttpClient.”_ – You need _delegation_ then. That’s a very different thing and requires a somewhat complex setup for Kerberos authentication. – poke Mar 23 '20 at 14:00

2 Answers2

1

I understand that locally it runs with current user, but I don't know how to authorize the Application Pool...

As poke and lex says, if you hosted on the IIS, the DefaultCredentials will be the application pool identity not the user account.

If you want to know how to modify the application pool identity, I suggest you could follow below steps:

1.Open the IIS management console.

2.Select the application pool and advanced setting

enter image description here

3.Modify the application pool identity to use custom domain account.

enter image description here


Update:

If you want to use login in user credential to access other api, I could try to use Impersonation.

        var user = (WindowsIdentity)User.Identity;


        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            var message =
                $"User: {impersonatedUser.Name}\t" +
                $"State: {impersonatedUser.ImpersonationLevel}";

            //ViewBag.UseImper = message;

            HttpClient Client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
            //Client.BaseAddress = new Uri("http://localhost:44331");
            Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            Client.DefaultRequestHeaders.Add("Application-Name", Assembly.GetExecutingAssembly().GetName().Name);

            var response = Client.GetAsync("http://127.0.0.1:44319/api/values").Result;

            int i = 0;

        });
Brando Zhang
  • 22,586
  • 6
  • 37
  • 65
  • I have expressed myself incorrectly. It is not what I want. I want to pass-through the authentication from the local user to the HttpClient – Eugen Kehl Mar 23 '20 at 07:15
  • If you want to use login in user credential to access other api, I could try to use Impersonation. – Brando Zhang Mar 24 '20 at 05:15
  • Hello Brando. I've already tried it, but then I get the following error: `This is usually a temporary error during hostname resolution and means that the local` – Eugen Kehl Mar 24 '20 at 06:37
  • It should use ip address instead of the domain when you send the request. – Brando Zhang Mar 24 '20 at 06:46
  • Now I get `StatusCode: 401, ReasonPhrase: 'Unauthorized'` again. But impersonation works. – Eugen Kehl Mar 24 '20 at 07:41
0

There seems to be a difference in behavior between using WebClient and HttpClient.

Please try with WebClient. It seems to give the proper credentials to the child request in contrast to HttpClient which is not allowed to spawn a child thread while impersonated.

Dale K
  • 25,246
  • 15
  • 42
  • 71
nttakr
  • 1,637
  • 15
  • 25
  • There are also 2 solutions for ,NET 4.6 and .NET Core here: https://stackoverflow.com/a/39971816/577717 and https://stackoverflow.com/a/48649925/577717 – nttakr Jun 08 '20 at 14:51