【问题标题】:Impersonation issue when making web request to other server向其他服务器发出 Web 请求时的模拟问题
【发布时间】:2017-02-28 18:36:58
【问题描述】:

我有一个 Intranet MVC.NET 网站。我们称之为 MySite。从 MySite 我正在尝试向另一个 Intranet 网站发出 Web 请求。我们将另一个网站称为 OtherSite。两个网站都在同一个域中,并且在 IIS 下运行。两个网站都在使用:

<authentication mode="Windows" />
<authorization>
  <allow verbs="OPTIONS" users="*" />
  <deny users="?" />
</authorization>

MySite 由经过身份验证的用户(同一域)通过网络浏览器(Chrome、IE)访问。我们称该用户为 Client。当 MySite 调用 OtherSite 时,应使用来自 Client 的凭据。

我尝试了以下方法:

WebRequest:

var request = WebRequest.CreateHttp(uri);
request.Credentials = CredentialCache.DefaultCredentials;
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
var response = request.GetResponse();
return response;

使用WebClient,建议here

using (var client = new WebClient { UseDefaultCredentials = true })
{
    client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
    var data = client.DownloadData(uri);
    return data;
}

周围有和没有这段代码:

var wi = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;
var wic = wi.Impersonate();
try
{
    // Code for making request goes here...
}
catch (Exception exc)
{
    // handle exception
}
finally
{
    wic.Undo();
}

我已经尝试在 MySite 的 web.config 中使用和不使用 &lt;identity impersonate="true" /&gt;

一旦我尝试冒充 客户,我就会从 OtherSite 收到 401。当我检查 OtherSite 的 IIS 日志时,看起来凭据根本没有随请求一起传递。

如果我不冒充用户,一切都会很好。但是一旦我尝试模仿它就会失败并返回401。我必须在 Active Directory 中执行任何操作吗?我见过this question,答案是授权。是这个问题吗?我冒充时收到401 的原因是什么?

当我模拟时,OtherSite 上的 IIS 日志如下所示:

2016-10-19 07:33:26 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 - 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 401 0 0 0
2016-10-19 07:33:26 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 - 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 401 1 2148074252 0

当我不冒充时,它们看起来像这样:

2016-10-19 07:57:11 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 MyDomain\SVC_ServiceAccount1 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 200 0 0 0
2016-10-19 07:57:11 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 MyDomain\SVC_ServiceAccount1 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 200 0 0 0

我有一个应用程序池的服务帐户,在上面的日志中名为 MyDomain\SVC_ServiceAccount1。真名是另外一回事……

【问题讨论】:

  • 为了让 MySite 将凭据委托给 OtherSite,用户需要使用 Kerberos 或 auth/plaintext 进行身份验证。如果是 Kerberos,则 IIS 进程将需要“信任委托”。
  • @Ben,谢谢。我试试看。

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


【解决方案1】:

如果您的 MVC 站点在 IIS 中运行,那么它在哪个应用程序池中运行?

您可能需要将该应用程序池设置为在特定身份下运行,否则它将尝试使用机器身份访问远程资源。

编辑(响应 cmets)

我的下一个想法是 IIS 也被配置为匿名访问,这就是正在传递的内容。在 IIS 管理控制台中,当您查看该站点的身份验证时,它会说什么?您在这里谈论的设置是关于授权而不是身份验证。

如果您尝试在 IIS 中禁用匿名身份验证(我会在确保没有徘徊的工作进程之后执行iisreset)并只留下 Windows 身份验证并启用会发生什么?

这就是我在代码中执行设置的方式(注意我使用的是 HttpClient)

protected HttpClient SetupHttpClient(string uri)
{
   HttpClient client = new HttpClient {BaseAddress = uri};
   client.DefaultRequestHeaders.Accept.Clear();            
   client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
   return client;
}   

【讨论】:

  • 我更新了问题。我有一个运行应用程序池的特定服务帐户。
  • 匿名身份验证是否关闭(在 IIS 中)?
  • 是的。 &lt;deny users="?" /&gt;,但我允许 &lt;allow verbs="OPTIONS" users="*" /&gt;。它在问题的顶部。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 2022-01-12
  • 2021-01-27
相关资源
最近更新 更多