user979331
user979331

Reputation: 11861

ASP.NET MVC Impersonate not working with Forms Authentication

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);
}

Upvotes: 2

Views: 1640

Answers (4)

Reza Aghaei
Reza Aghaei

Reputation: 125197

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:

Upvotes: 3

Aidan Black
Aidan Black

Reputation: 593

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

Upvotes: 0

Hamit YILDIRIM
Hamit YILDIRIM

Reputation: 4539

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

Upvotes: 0

salli
salli

Reputation: 782

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

Upvotes: 0

Related Questions