Impersonate user to access file on remote server -

2019-07-26 14:30发布

问题:

I have an MVC web application that is supposed to allow users to download files that are stored as UNC paths in a database. These files can be in any number of locations on remote servers/shares.

E.g. Server 1 hosts the web application that is used to download a file stored on Server 2

I do not want to give permissions to these folders to the hosting service account, as the security should be dependent on what the user has access to. Therefore, I'm attempting to use Impersonation to retrieve the file.

When I debug on my local machine, everything works great. It impersonates my user and downloads the file.

When I deploy to my test server, I'm getting the following error:

Access to the path '\\Server2\SharedFolder\somefile.txt' is denied

I've tried various pieces from this Microsoft link, but am not having much luck.

Scenarios I've tried:

  1. Just giving the permission to the service account of the AppPool works fine, but as I said, isn't ideal
  2. Implementing the Impersonate a Specific User in Code from the above article, which works perfectly with a hard-coded user and password. This situation is also not ideal.
  3. Implementing the Impersonate the Authenticating User in Code from the above article. This seems to be exactly what I need, but this is what generates the Access Denied error.

The Code that I want to work:

System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =   
    ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

//Code to read all bytes from the file path

impersonationContext.Undo();

I have logging, and System.Security.Principal.WindowsIdentity.GetCurrent().Name after the impersonation does return the intended user (my account instead of the service account), so it does appear to be working.

I thought maybe it was a double-hop thing, so I have also added SPNs for the server and the service account, making sure their Delegation in AD was set to allow for any service. That hasn't helped either.

This question seems to have the exact same problem as me, but there's no follow-up on what the final solution was. I did try the Process Monitor part, but it didn't help at all.

I'm at a loss to why Impersonation seems to be working, but I'm denied access to a file on a second server.

Update 1 I've played around more with my IIS settings and trying to get Kerberos properly set up. The only thing enabled in my IIS Authentication is "Windows Authentication".

When I spit out details after my Impersonate() call, I'm finding that ImpersonationLevel = Impersonation

Is that how it should be, or should that be returning Delegation ?

回答1:

It would seem the issue was mostly due to my setup with Kerberos and SPNs. I undid all my settings and re-registered my service account, and the Impersonation ended up working properly.

The issue now is that it only seems to work with Internet Explorer. Chrome and MobileIron are doing something different that prevents the ImpersonationLevel of Delegation. That's a whole other question...