Jul*_*ian 9 c# dotnet-httpclient asp.net-core httpclientfactory
背景
我正在开发 ASP.NET Core Web API,我们在 API 中调用第三方 API。此第 3 方 API 要求每个请求都包含带有访问令牌的 cookie。我们的 API 从声明(来自与ClaimsPrincipal请求关联的用户的)中获取此令牌。
详细信息
此答案显示了如何在请求上设置 cookie,但该示例要求手动构造HttpClient(以便能够使用 a 注入HttpClientHandlera CookieContainer)。由于不希望手动实例化HttpClient,我宁愿HttpClient通过 DI 进行注入,本例说明了这一点(使用IHttpClientFactory)。
在我的服务中,我可以访问注入的实例HttpClient(_httpClient),最简单的函数如下所示:
public async Task<string> GetStatusAsync(ClaimsPrincipal user)
{
// TODO: Add cookie with access token (from user's claims) before making request
return await _httpClient.GetStringAsync(Endpoints.Status);
}
Run Code Online (Sandbox Code Playgroud)
这个GitHub问题询问如何在使用IHttpClientFactory时包含授权cookie,答案说使用标头传播中间件。现在我的问题是:
据我所知,您在应用程序启动时的服务配置期间设置了标头传播中间件(包含所有标头和 cookie 等)。然而,在我们的 API 中,在实际向第 3 方 API 发出请求之前,我没有身份验证 cookie 的值。
问题在发出实际请求之前,
如何将 cookie 添加到HttpClient使用 注入到我的服务的实例上的请求?IHttpClientFactory
解决方案确实是使用标头传播。我只需要把所有的部分正确地组合在一起。
标头传播在内部配置ConfigureServices(in Startup.cs)。由于我想使用当前用户声明中的数据,所以技巧是,在添加 cookie 标头时,使用接受允许您访问当前上下文的函数的重载:
services.AddHeaderPropagation(options =>
{
options.Headers.Add("Cookie", context =>
{
var accessToken = context.HttpContext.User.Claims.FirstOrDefault(c => c.Type == "access-token")?.Value;
return accessToken != null ? new StringValues($"token={accessToken}") : new StringValues();
});
});
Run Code Online (Sandbox Code Playgroud)
除此之外,由于我使用的是Typed Service,所以我还必须配置该特定服务应转发 cookie 标头(在 中的同一位置ConfigureServices)Startup.cs:
services.AddHttpClient<IApiService, ApiService>(httpClient =>
{
httpClient.BaseAddress = new Uri("https://httpbin.org/");
}).AddHeaderPropagation(options =>
{
options.Headers.Add("Cookie");
});
Run Code Online (Sandbox Code Playgroud)
最后,给我带来了一些麻烦的事情是:由于我使用的是当前用户声明中的数据,因此标头传播中间件(app.UseHeaderPropagation();inside Configurein )的注册必须在添加身份验证中间件( )之后Startup.cs进行。如果没有,则索赔尚未确定。app.UseAuthentication();
最后提示:在处理此问题时,我会在https://httpbin.org/上向我们致意。请求检查端点对于查看您在请求中实际传递的数据非常有用。
| 归档时间: |
|
| 查看次数: |
8567 次 |
| 最近记录: |