1 回答
TA贡献1852条经验 获得超7个赞
尝试使用HttpClientFactory添加了 Asp.Net Core 2.1 的 ,结合HttpMessageHandler以实现您正在尝试做的事情。
ConfigureServices您可以在方法中注册 HttpClient
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<BaseClient>(client =>
{
client.BaseAddress = new Uri("yrl");
client.DefaultRequestHeaders.Add("Accept", "application/json");
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});
}
使用上面的代码,您BaseClient将通过 DI 接收 HttpClient 实例。
为了验证/检查,AuthHeader您可以HttpMessageHandler为已注册的HttpClient. 消息处理程序的代码很简单,如下所示:
public class AuthHeaderHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (!request.Headers.Contains("Authorization"))
{
return new HttpResponseMessage(HttpStatusCode.Forbidden)
{
Content = new StringContent("No Authorization header is present")
};
}
return await base.SendAsync(request, cancellationToken);
}
}
为了注册上述处理程序,您的代码将如下所示:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<AuthHeaderHandler>();
services.AddHttpClient<BaseClient>(client =>
{
//code omitted for brevity
...
})
.AddHttpMessageHandler<AuthHeaderHandler>();
}
如果需要,您可以在消息处理程序中注入任何需要的内容。但是,无需在BaseClient. 要阅读有关 HttpClientFactory 和 HttpMessageHandlers 的更多信息,请参阅此链接和此。我希望这有帮助。
更新的答案
请查看使用 IHttpContextAccessor 并修改 HttpRequestMessage 的更具体的 HttpMessageHandler 示例,即在调用之前添加 Authorization 标头。您可以根据需要修改逻辑。
public class AuthHeaderHandler : DelegatingHandler
{
private readonly HttpContext _httpContext;
public AuthHeaderHandler(IHttpContextAccessor contextAccessor)
{
_httpContext = contextAccessor.HttpContext;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
if (_httpContext != null)
{
var accessToken = await _httpContext.GetTokenAsync(TokenKeys.Access);
if (!string.IsNullOrEmpty(accessToken))
{
// modify the request header with the new Authorization token
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}
}
return await base.SendAsync(request, cancellationToken);
}
}
更新的答案 2
请查看我已上传到 GitHub的简单解决方案。该解决方案甚至比我最初建议的还要简单。由于您没有集成任何基于身份的身份验证/授权,您可以简单地使用我称之为 CustomActionFilter 的 CustomActionFilterValidateAuthHeader来检查 AuthHeader 是否存在,如果不存在则返回通常的 403。
在 中ValidateAuthHeader,我使用了您之前发布的中间件代码。然后,您可以简单地将此属性添加到需要此检查的 ActionMethods 或 Controllers 上。
请查看DataController和ValuesController。将DataController接收HttpClient将用于调用values端点的类型。ValidateAuthHeader出现在 上GetValues并将检查 AuthHeader。如果它不存在,它将产生错误。
[Route("api/[controller]")]
[ApiController]
public class DataController : ControllerBase
{
private readonly MyHttpClient _client;
public DataController(MyHttpClient client)
{
_client = client;
}
[ValidateAuthHeader]
public async Task<IActionResult> GetValues()
{
var response = await _client.GetAsync("api/values");
var contents = await response.Content.ReadAsStringAsync();
return new ContentResult
{
Content = contents,
ContentType = "application/json",
StatusCode = 200
};
}
}
流程的其余部分与我最初建议的相同。调用将通过AuthHeaderHandler已HttpMessageHandler注册的MyHttpClient. 请看一看Startup.cs。
处理程序将检索HttpContextviaHttpContextAccessor并检查AuthHeader. 如果存在,它将把它添加到 RequestMessage 参数中。
我希望这有帮助。如有任何问题,请随时提出。
不使用 HttpMessageHandler 设置 Auth Header
修改 MyHttpClient 并添加一个名为的公共方法SetAuthHeader
public class MyHttpClient
{
private readonly HttpClient _httpClient;
public MyHttpClient(HttpClient client)
{
_httpClient = client;
}
public void SetAuthHeader(string value)
{
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", value);
}
}
然后在您的操作方法中调用此方法,因为此时您将在 HttpContext.Request 中拥有 AuthHeader
[ValidateAuthHeader]
public async Task<IActionResult> GetValues()
{
var authHeader = Request.Headers["Authorization"];
_client.SetAuthHeader(authHeader.First());
var response = await _client.GetAsync("api/values");
var contents = await response.Content.ReadAsStringAsync();
return new ContentResult
{
Content = contents,
ContentType = "application/json",
StatusCode = 200
};
}
去掉AuthHeaderHandler注册,删除AuthHeaderHandler。
- 1 回答
- 0 关注
- 112 浏览
添加回答
举报