1

I have an ASP.NET Core 5 web app (actually a blazor server app) and another ASP.NET Core 5 Web API, both running on IIS in a domain environment.

I have configured Windows auth so that users can authenticate with the Blazor server app, and this returns the expected domain user's identity from the HttpContext.

If I use the Web API through Swagger to get the users identity from the HttpContext, I also get the expected domain user's identity. However if naively call from the Blazor server app using the HttpClient (given by DI) to the Web API, I get the app pool identity for the user instead.

There are hundreds of posts on this subject and why this happens (i.e.)

https://github.com/dotnet/runtime/issues/17828

.Net Core WindowsIdentity impersonation does not seem to be working

However my question is essentially even if I do manage to get the stars to align and get all the infrastructure config correct is there any way to get the middleware to provide an HttpClient that is already "impersonated" or am I forced to wrap every use of HttpClient something like this:

https://stackoverflow.com/a/66511109/29411

IPrincipal p = _httpContextAccessor.HttpContext.User;

HttpResponseMessage result = null;

if (p.Identity is WindowsIdentity wid)
{
    await WindowsIdentity.RunImpersonated(wid.AccessToken, async () =>
                     {
                         result = await _client.GetAsync("APIController/Action");
                     });
}
Zhi Lv
  • 18,845
  • 1
  • 19
  • 30
Christopher Edwards
  • 6,589
  • 8
  • 43
  • 57
  • You could try to use a named client integrating the impersonation logic. Look at this answer for delegated client: https://stackoverflow.com/questions/15380054/verify-that-the-currently-authenticated-windows-user-has-delegation-rights – Nicola Biada Aug 17 '21 at 17:19
  • I think the code you post is the most suitable method at present. This [thread](https://stackoverflow.com/a/12675503/14162739) explains that why need to wrap every use of httpclient, though it recommend use webclient. – Bruce Zhang Aug 18 '21 at 07:33

1 Answers1

1

.Net 5 running Impersonated (I am running this in Blazor Server)

I have only recently solved this so at present I think everything will need to be wrapped but I'll update if I find anything that solves that.

I have seen a lot of references to using an IHttpConextAccessor and lots of problems with this being null. This article from Microsoft suggests that this shouldn’t be used (Certainly in Blazor) MS-Docs

Solution: To get the user to impersonate use the AuthenticationStateProvider and get the user from this and cast to a WindowsIDentity to retrieve the AccessToken. This works in both a service and a razor component. Inject the AuthenticationStateProvider and then in your method use the following code:

    var authState = await _authenticationStateProvider.GetAuthenticationStateAsync();
    var user = authState.User;
    var userToImpersonate = (WindowsIdentity)user.Identity;
    
    await WindowsIdentity.RunImpersonatedAsync(userToImpersonate.AccessToken, async () => 
  {
    
      // Your Code in here
    
  }
Ren
  • 59
  • 5
  • That isn't working for me (at least not yet, this may be an IIS config issue). Even if I did get it working I'd really prefer to get my HttpClient instance already impersonated using DI. – Christopher Edwards Sep 06 '21 at 09:34
  • Indeed, me too. It's on the list but I spent long enough getting to this stage and I need to get my other work done! I will revisit it though when I move forward using this. – Ren Sep 07 '21 at 21:21
  • If you ever get this working with DI please post it here:) I have worked around the issue but it is a good workaround so I'd be interested if you ever got this wokring with DI. – Christopher Edwards Sep 09 '21 at 08:26
  • For folks that have HttpContextAccessor as null - I ran into this and didn't know I needed to add services.AddHttpContextAccessor();. – Travis L. Riffle Sep 07 '22 at 19:45