ASP.NET MVC模拟无法与表单身份验证一起使用

时间:2020-02-07 16:39:21

标签: c# asp.net asp.net-mvc iis impersonation

我正在尝试运行以下代码:

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

但是除非我冒充用户,否则不能。在我的web.config中,我将模拟设置为true,如果我在那里设置凭据,则该行代码将按预期工作。

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

这不起作用:

<identity impersonate="true" />

当我运行此代码时:

System.Security.Principal.WindowsIdentity.GetCurrent()

我可以看到它填充了正确的用户名,并且模拟设置为true

那么,当我的用户可以模拟时,为什么此行代码不运行?

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

请帮助!

更新

这是我用来登录活动目录的登录方法。

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

4 个答案:

答案 0 :(得分:2)

关注以下问题:那么,为什么这行代码没有运行...

这里是没有模拟或带有或没有用户/密码的模拟的意思:

  • Impersonation is disabled

    应用程序池标识用于运行应用程序代码。

  • <identity impersonate="true"/>

    IUSR用于运行应用程序代码。

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

    指定用户的身份将用于运行应用程序代码。

现在知道含义了,当您指定不带用户名和密码的身份模拟时,这意味着您要求使用IUSR运行应用程序代码,该文件对文件系统上的指定路径没有足够的权限。

要解决此问题:

  • 您可能希望向IUSR授予更多权限。
  • 或者您可能希望通过指定在配置或代码中具有足够权限的用户名和密码来进行模拟
  • 或者您可能希望以具有足够许可权的应用程序池标识运行该应用程序。
  • 或者您可能希望使用集成Windows身份验证和配置作为explained here进行委派。

要了解有关身份和假冒的更多信息,请查看以下资源:

答案 1 :(得分:1)

考虑使用模拟窗口进行身份验证。作为Windows用户,对私有资源的访问比Web用户具有更高的优先级和可访问性。在这种情况下,默认情况下将无法模拟IIS用户。

此外,总有解决方案。过去,我们在Windows中导入dll以解决此问题。现在,我将数据保护证书放在.net核心应用程序上。您可以像这种实现那样访问活动目录。我正在接触Redis机器。

        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端应定义为匿名和集成用户。这段代码将为您提供特殊资源

答案 2 :(得分:0)

确保IUSR或运行应用程序池的帐户对FilePath文件夹具有读/写访问权限。

答案 3 :(得分:0)

您使用哪种浏览器对此进行测试? Edge和Chrome应该自动将Windows凭据传递给您的应用程序,但是在Firefox中,您需要在about:config中修改设置,具体方法如下:https://superuser.com/questions/29624/how-can-i-make-firefox-behave-like-ie-on-a-windows-domain-when-requesting-user-c