2

I am trying to run this code:

File.WriteAllText(FilePath + Description + "-" + ID + ".txt", FileContent);

But cannot unless I am impersonating a user. In my web.config I have impersonate set to true, if I set the credentials there that line of code works as expected.

<identity impersonate="true" userName="domain\username" password="password" />

This does not work:

<identity impersonate="true" />

When I run this code:

System.Security.Principal.WindowsIdentity.GetCurrent()

I can see that it is populated with the correct username and impersonate is set to true.

So, why is this line of code not running, when my user can impersonate?

File.WriteAllText(FilePath + Description + "-" + ID + ".txt", FileContent);

PLEASE HELP!

UPDATE

This is my login method that I am using to login against the active directory.

[HttpPost]
public ActionResult Index(Login model, string returnUrl)
{
    if (!ModelState.IsValid)
    {

        ModelState.AddModelError("", "The user name or password provided is incorrect.");

        return View(model);
    }

    if (Membership.ValidateUser(model.UserName, model.Password))
    {
        FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
        if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
            && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
        {
            return Redirect(returnUrl);
        }

        return RedirectToAction("Index", "Home");
    }

    ModelState.AddModelError("", "The user name or password provided is incorrect.");

    return View(model);
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
user979331
  • 11,039
  • 73
  • 223
  • 418
  • I'm assuming that you don't use any form of authentication on your site, and that IIS is configured for anonymous access? I also assume that your web server is joined to your domain? What version of IIS are you running on? What error do you get when this fails? – Jeremy Caney Feb 09 '20 at 21:25
  • I see that you opened [another question with an identical +500 reputation bounty](https://stackoverflow.com/questions/60115948/impersonate-user-with-forms-authorization). That question is more detailed, but appears to pertain to the exact same problem. Was this intentional? Or is there a nuance to the question that I'm missing? – Jeremy Caney Feb 09 '20 at 21:31
  • would [this SO thread](https://stackoverflow.com/questions/4334665/steps-to-enable-double-hop-delegation-in-iis7-windows-2008) be of use to you? – timur Feb 10 '20 at 07:22
  • If you are using Forms Authentication, the only way to impersonate Windows User Identity is having username and password of the user. – Reza Aghaei Feb 10 '20 at 13:03
  • Log in using Active Directory != Windows Authentication. You are using `Membership.ValidateUser`, no matter what provider you are using, it's forms authentication. Active Directory here in this authentication, plays role of Membership Database, nothing more than that. – Reza Aghaei Feb 12 '20 at 20:23
  • It may be disappointing for you and you may don't like the answer, but unfortunately it is what it is. – Reza Aghaei Feb 12 '20 at 20:25

4 Answers4

3

Focusing on the question: So, why is this line of code not running ...

Here is the meaning of not having impersonation or having it with or without user/password:

  • Impersonation is disabled

    The application pool identity is used to run the application code.

  • <identity impersonate="true"/>

    IUSR is used to run the application code.

  • <identity impersonate="true" userName="accountname" password="password"/>

    Identity of the specified user will be used to run the application code.

Now knowing the meanings, when you specify identity impersonation without username and password, it means you are asking to run application code using IUSR which doesn't have enough permission to the specified path on the file-system.

To fix the problem:

  • You may want grant IUSR with more permission.
  • Or you may want to do impersonation by specifying a username and password which has enough permission in config or in code
  • Or you may want to run the application under an application pool identity which has enough permission.
  • Or you may want to use Integrated Windows Authentication and config for delegation as explained here.

To learn more about identity and impersonation take a look at these resources:

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
0

Make sure IUSR or the account that is running the application pool has read/write access to the FilePath folder.

salli
  • 722
  • 5
  • 10
0

Consider impersonation windows to work with authentication. As a Windows user, access to private resources is more priority and accessible than the web user. In this case, it is not possible to emulate an IIS user by default.

Besides, there is always a solution. In the past, we were importing dll in windows to solve this issue. Now I am placing a data protected certificate on my .net core app. You can access the active directory like this implementation. Which i am reaching to redis machines.

        services.AddDataProtection().ProtectKeysWithDpapi(protectToLocalMachine: true);

        services.AddDataProtection()
            .ProtectKeysWithCertificate(
                new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "clientCert.pfx"), "password",
                 X509KeyStorageFlags.MachineKeySet
                         | X509KeyStorageFlags.PersistKeySet
                         | X509KeyStorageFlags.Exportable)
            )
            .UnprotectKeysWithAnyCertificate(
                new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "clientCert.pfx"), "password",
                            X509KeyStorageFlags.MachineKeySet
                         | X509KeyStorageFlags.PersistKeySet
                         | X509KeyStorageFlags.Exportable
                )
            );

        services.Configure<StorageConfiguration>(new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build());
        var redisConf = Configuration.GetSection("RedisConnection").Get<RedisConnection>();
        ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(redisConf.Host.ToString() + ":" + redisConf.Port.ToString());
        services.AddDataProtection().PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
        services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect(redisConf.Host.ToString() + ":" + redisConf.Port.ToString()));

IIS side should be defined as anonymous and integrated user. And this code will provide you to reaching special resources

Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35
0

What browser are you using to test this? Edge and Chrome should pass Windows credentials to your app automatically, but in Firefox you need to modify a setting in about:config, per this answer: https://superuser.com/questions/29624/how-can-i-make-firefox-behave-like-ie-on-a-windows-domain-when-requesting-user-c

Aidan Black
  • 593
  • 6
  • 17