Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set up impersonation with ASP.NET

for a first understanding, I have created a very simple project which tries to count the number of files in two directories. User1 is not allowed to access Directory2 and User2 is not allowed to access Directory1. Due to impersonation I should get only one number, depending on the user who is calling my application. Both user are set up as administrators.

So I have created a new MVC-project in Visual Studio 2015 (running on Windows 8.1) and selected to use Windows authentication. Once the application is up and running (in ISS Express), I switch to User1 on my machine (there is no Active Directory) and call the website in Internet Explorer (yes, "Integrated Windows authentication" is enabled in the settings). With this setup, the user in HttpContext.User.Identity is User1 and WindowsIdentity.GetCurrent() is my development user, the one I am working with in Visual Studio.

I have also tried to impersonate manually:

WindowsIdentity winId = (WindowsIdentity)User.Identity;
WindowsImpersonationContext ctx = null;
try
{
    ctx = winId.Impersonate();

    // GetNumbers() tries to get the number of files for both directories       
    numbers = GetNumbers();
}
catch (Exception e)
{
}
finally
{
    if (ctx != null)
    {
        ctx.Undo();
    }
}

Unfortunately, I get the exception "Either a required impersonation level was not provided, or the provided impersonation level is invalid." Some people were claiming the this one solved their problem: https://kc.mcafee.com/corporate/index?page=content&id=KB56194 Not for me. I've added User1 and my own user to the lists and restarted the computer. No change.

The only thing which gives me a little bit of hope is the impersonation with a separate login, as described on https://msdn.microsoft.com/en-us/library/ms998351.aspx#paght000023_impersonatingusinglogonuser The disadvantages are quite obvious: I have to have the user's password and why should I login again if the user already did it for me.

Although this is a new project without major changes by me, some more information just for sanity check...

My Web.config

<authentication mode="Windows" />
<authorization>
  <deny users="?" />
</authorization>

My project settings are

  • "Anonymous authentication" is false
  • "Windows authentication" is true
  • "Managed pipline mode" is Integrated

Any suggestions on what to change to make this simple project work as expected?

Best regards, Carsten

like image 624
Carsten Franke Avatar asked Sep 19 '16 11:09

Carsten Franke


People also ask

How do you do impersonation in C#?

To impersonate the IIS authenticating user on every request for every page in an ASP.NET application, we must include an <identity> tag in the Web. config file of this application and set the impersonate attribute to true.

Where do you put impersonate true in web config?

In the application's Web. config file, set the impersonate attribute in the identity element to true. Set the NTFS access control list (ACL) for the ManagerInformation directory to allow access to only those identities that are in the Windows Manager group and any required system accounts.

How do you use impersonate?

How to use Impersonate in a sentence. I agree that a genuine Guide would never impersonate anyone. Attempting to impersonate any person by using forged headers or other identifying information is prohibited. Putting information out there on social networks can allow someone to take that information and impersonate you.

What is impersonation in MVC?

With impersonation, if the client is connecting using the original caller's account, the service will access resources such as a SQL Server database on the same machine using the original caller's account instead of the system ASP.NET account.


1 Answers

I finally managed to get it to work (IIS Express and IIS)! As mentioned above, the first approach was a prototype only. The final goal was to create a GUI which runs on server A and an API which runs on server B. Both implemented with ASP.NET.

The Web.config of the GUI and the API got these settings:

<system.web>
  <authentication mode="Windows" />
  <authorization>
    <deny users="?" />
  </authorization>
  <identity impersonate="true" />
</system.web>

The project property (press F4 after selecting the project) "Managed pipline mode" is set to Classic.

Somewhere on SO I saw a discussion about if the impersonation should work with HttpClient as well. It was said, it does. Well, it did not for me. And the WebClient is no fun if you are using a variety of HTTP methods. So I switched to RestSharp:

RestClient client = new RestClient(baseUrl);
client.Authenticator = new NtlmAuthenticator();
  • Special note for Visual Studio: You have to start Visual Studio as administrator or else the impersonation will not work on IIS Express!
  • Special note for IIS: The application pool has to use Classic "Managed pipeline mode".
  • Special note (while testing): At first, the API asked me to authenticate, which it should not. The reason was quite simple: My user user1 on my development machine had another password then the user1 on my target machine...

I hope this helps someone.

like image 191
Carsten Franke Avatar answered Oct 11 '22 07:10

Carsten Franke