繁体   English   中英

ASP.Net Core 3.1 WebClient 使用应用程序池凭据访问其他具有 Windows 身份验证的 API

[英]ASP.Net Core 3.1 WebClient to Use Application Pool Credential to Access Other API that has Windows Authentication

我正在使用 C# ASP.Net Core 运行时开发 API,我计划在 IIS 中托管它。

其中一个要求是从另一个 RESTful API 服务器获取信息,该服务器当前具有 windows 身份验证(LDAP 身份验证)。

我已经有了使用服务帐户的解决方案,该服务帐户在 appsettings.json 中硬编码服务帐户名称和密码。

代码如下

var serviceApi = _config["Api:ServiceApi"].ToString(); // this is the URL of other RESTful API from appsettings.json
var serviceAccount = _config["ServiceAccount:UserName"].ToString(); // service account username from appsettings.json
var serviceAccountPwd = _config["ServiceAccount:Password"].ToString(); // service account password which is currently shown as clear text in appsettings.json
var serviceAccountDomain = _config["ServiceAccount:Domain"].ToString(); // service account domain name from appsettings.json
var client = new WebClient();
CredentialCache cc = new CredentialCache();
cc.Add(
    new Uri(serviceApi),
    "NTLM",
    new NetworkCredential(serviceAccount, serviceAccountPwd, serviceAccountDomain));
client.Credentials = cc;
client.Headers["Content-Type"] = "application/json";
string response = client.DownloadString($"{serviceApi}/User");

此解决方案的缺点是,服务帐户的密码在 appsettings.json 中可见。 我需要其他不会以明文形式公开密码的解决方案。

我能想到的解决方案之一是将服务帐户信息存储在 IIS 应用程序池标识中。 但是,我仍然无法让 WebClient 使用 IIS 应用程序池标识。 到目前为止,我可以做些什么来让 WebClient 使用我自己的来自 windows 的 NTLM 凭证。

这是代码

var serviceApi = _config["Api:ServiceApi"].ToString();
var client = new WebClient();
client.UseDefaultCredentials = true; // this is not getting credential from IIS app pool identity but rather from logged in account in windows operating system
client.Headers["Content-Type"] = "application/json";
string response = client.DownloadString($"{serviceApi}/User");

请帮助我了解如何使用 IIS 应用程序池身份作为其他 RESTful API 应用程序的凭据?

最终我们发现我们无法实现这一点,因为从技术上讲,它会损害登录用户的安全性,除非您在 API 服务器上启用 Windows/NTLM 身份验证(这需要浏览器/客户端主动启用与服务器)。

我们最终使用的解决方案是使用预共享密钥,以 AppId 和 AppSecret 的形式,这似乎是标准方法。 本质上,我们向调用应用程序发出了存在于 AD 之外的用户名和密码。

似乎您对 Windows 身份验证有一些误解。

  1. Windows 集成认证不是 LDAP 认证。
  2. LDAP 是一种用于查询数据的有线协议,类似于 SQL,在 OSI model 上与 model 处于同一级别。
  3. WIA 设计为在 HTTP 中使用时绝不允许用户的密码离开浏览器(但是 NTLM 非常不安全,因为已知 LM hash 已被破坏)。

所以,鉴于以上所有。 您想在前端 Web 服务器和后端 Web 服务器之间使用 Windows Integrated Security with Kerberos SPNEGO。

以下将是一个简短的故障排除指南。

  • 后端服务器将我的服务标识为 [MachineName]。 这是因为您使用的是非 AD 帐户来运行您的应用程序。 使用 InProcess 托管并使用 AD 服务帐户创建一个新的 AppPool 来运行应用程序。
  • 后端服务器将我的服务识别为 [Web Browser user]。 这在生产环境中不太可能偶然发生。 如果出现这种情况,当浏览器、前端和后端都在不同的PC上时,这一定意味着你不小心打开了Windows Auth、Windows Impersonation、Kerberos Authentication,并在前端和后端之间设置了委派的SPN。 一切都不会出错。 我花了几个月的时间来故意这样做。
  • 强制我们禁用 NTLM 身份验证和 Kerberos 的权力不起作用。 您的问题很可能是在您的 AD 上为 http 地址设置 SPN 以指向您的 AppPool 身份(这又必须是 AD 帐户或机器帐户)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM