我如何使用具有模拟功能的HttpClientFactory?还是找到另一种基于Windows身份从服务获取JWT令牌的方法?

问题描述 投票:0回答:1

我有一个常规的ASP.Net Core网站,用户可以使用Windows身份验证来访问该网站,以确定哪些用户可以访问哪些页面。

为了为用户呈现页面,站点需要调用一系列Web服务来获取各种数据。这些Web服务不使用Windows身份验证。相反,它们需要用户的JWT令牌。

因此,我们的WebSite需要将用户的Windows令牌交换为JWT令牌。我们有一个特殊的ExchangeToken Web服务,该服务使用Windows身份验证接受请求,并返回用户的JWT令牌。

当我希望WebSite调用此ExchangeToken Web服务时,困难就来了。我需要使用模拟来调用它,以便可以重新获得用户的JWT令牌。但是,似乎无法将HttpClient与模拟一起使用。

起初,我计划在WebSite中这样做:

  1. 反复...
  2. 模拟用户
  3. 实例化HttpClient
  4. 调用TokenExchange服务以获取JWT令牌
  5. 处置HttpClient
  6. 停止模拟
  7. 返回令牌

但是,根据what I've read,为每个调用重新创建HTTP客户端是不好的做法,而我should be使用HttpClientFactory instead

但是,我不知道这种方法如何与模拟一起使用。

我尝试过:

  1. 使用HttpClientFactory创建HttpClient
  2. 反复...
  3. 模拟用户
  4. 调用TokenExchange服务以获取JWT令牌
  5. 停止模拟
  6. 返回令牌

但是,发生的是,尽管有模拟,对<< all >>的TokenExchange服务的调用还是使用same Windows凭据进行的-Windows凭据是碰巧首先访问该网站的用户的凭据。 AFAIK,这源于Windows身份验证的工作方式-在您使用HttpClient时first会执行令牌交换,此后,对该客户端的所有调用都使用相同的令牌。一种选择是为每个用户创建一个单独的客户端...但是我有大约7,000个用户,所以这似乎有点过分!

另一种选择是信任该WebSite代表用户使用其自己的帐户来获取令牌。问题在于它需要信任WebSite。如果它被攻击者攻破,那么我就无法阻止攻击者为任意用户窃取JWT令牌。而通过模拟,攻击者仍然无法在没有首先获得其Windows令牌的情况下获得用户的JWT令牌。

所以,有没有一种方法可以一起模拟+ IHttpClientFactory?还是有更好的方法来解决所有这些问题?

((如果很重要,我公司拥有自己的Windows服务器-我们还不在云中)

为了演示第二种方法的问题,我做了一个测试应用程序。它实际上并没有使用HttpClientFactory,但确实演示了该问题。

我从一个网站开始,该网站只返回拨打电话的用户:

[Authorize] [Route("api/[controller]")] [ApiController] public class WhoController : ControllerBase { [HttpGet] public ActionResult<string> Get() { return User.Identity.Name; } }

我的客户代码如下:

private void CallClient(HttpClient httpClient, string username, string password) { LogonUser(username, "MYDOMAIN", password, 2, 0, out IntPtr token); var accessTokenHandle = new SafeAccessTokenHandle(token); WindowsIdentity.RunImpersonated( accessTokenHandle, () => { string result = httpClient.GetStringAsync("http://MyServer/api/who").Result; Console.WriteLine(result); }); }

我的测试代码像这样调用它:

public void Test() { var httpClient = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true }); CallClient(httpClient, "User1", "Password1"); CallClient(httpClient, "User2", "Password2"); }

如上所述,我将以下内容写入控制台:

User1 User1

我想要的是:

User1 User2

我有一个常规的ASP.Net Core网站,用户可以使用Windows身份验证来访问该网站,以确定哪些用户可以访问哪些页面。为了为用户呈现页面,站点需要调用...
authentication .net-core jwt impersonation
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.