【问题标题】:ASP.NET MVC Impersonate not working with Forms AuthenticationASP.NET MVC 模拟不使用表单身份验证
【发布时间】:2020-05-23 20:05:36
【问题描述】:

我正在尝试运行此代码:

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

但除非我冒充用户,否则不能。在我的 web.config 中,我将 impersonate 设置为 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);
}

【问题讨论】:

  • 我假设您没有在您的站点上使用任何形式的身份验证,并且 IIS 配置为匿名访问?我还假设您的网络服务器已加入您的域?您在哪个版本的 IIS 上运行?失败时会出现什么错误?
  • 我看到你打开了another question with an identical +500 reputation bounty。该问题更详细,但似乎与完全相同的问题有关。这是故意的吗?还是我遗漏的问题有细微差别?
  • this SO thread 对你有用吗?
  • 如果您使用表单身份验证,模拟 Windows 用户身份的唯一方法是拥有用户的用户名和密码。
  • 使用 Active Directory 登录!= Windows 身份验证。您正在使用Membership.ValidateUser,无论您使用什么提供商,它都是表单身份验证。 Active Directory 在此身份验证中,扮演 Membership Database 的角色,仅此而已。

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


【解决方案1】:

专注于问题:那么,为什么这行代码没有运行...

以下是没有模拟或有或没有用户/密码的含义:

  • Impersonation is disabled

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

  • &lt;identity impersonate="true"/&gt;

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

  • &lt;identity impersonate="true" userName="accountname" password="password"/&gt;

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

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

解决问题:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      考虑使用模拟窗口进行身份验证。作为 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 端应定义为匿名和集成用户。此代码将为您提供获取特殊资源的途径

      【讨论】:

        【解决方案4】:

        你用什么浏览器来测试这个? 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

        【讨论】:

          猜你喜欢
          • 2011-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-21
          相关资源
          最近更新 更多