用户登录后,我验证他们的信息并生成 JWT 令牌。
身份验证过程发生在 var statusPublisher: AnyPublisher<Status, Never> {
$substatus1
.combineLatest($substatus2)
.map { s1, s2 -> Status in ... }
.eraseToAnyPublisher()
}
(它不是我的自定义处理程序)。
我在哪里以及如何保存这个令牌,以便它会随着 http 调用发送?由于 XSS 攻击,我不想将其保存在客户端。以下似乎也不起作用,因为我不会出现在每个请求中
Authentication
我找到了使用 HttpContext.Request.Headers.Append("Authorization", MyGeneratedJWTTokenAsString);
的答案,但还有其他安全的方法吗?
答案 0 :(得分:1)
在后端服务中使用 HttpClient
时,最好使用 IHttpClientFactory
生成客户端。
因此,我们要做的是使用此工厂(与 IHttpContextAccessor
结合)来生成具有当前用户授权方案和令牌的 HttpClient
对象。因此,将其添加到 ConfigureServices
Startup.cs
方法中
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddHttpClient("UserAuthorizedHttpClient", (sp, httpClient) =>
{
var accessor = sp.GetRequiredService<IHttpContextAccessor>();
if (accessor.HttpContext.Request.Headers.TryGetValue(
"Authorization", out var authHeaderValue) &&
AuthenticationHeaderValue.TryParse(
authHeaderValue, out var auth))
{
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(auth.Scheme, auth.Parameter);
}
else
{
// incase there is a value from a previous generation
if(httpClient.DefaultRequestHeaders.Contains("Authorization"))
{
httpClient.DefaultRequestHeaders.Remove("Authorization");
}
}
});
services.AddHttpContextAccessor();
// ...
}
为了使用这些特殊客户端,您只需将 IHttpClientFactory
注入需要发出 HTTP 请求的服务中:
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace YouApplicationNamespace.Services
{
public interface IMyHttpRequesterService
{
Task DoSomethingCoolAsync();
}
public sealed class MyHttpRequesterService : IMyHttpRequesterService
{
private readonly IHttpClientFactory _httpClientFactory;
public MyHttpRequesterService(IHttpClientFactory httpClientFactory) =>
_httpClientFactory = httpClientFactory;
public async Task DoSomethingCoolAsync()
{
var authroizedHttpClient =
_httpClientFactory.CreateClient("UserAuthorizedHttpClient");
var resp = await authroizedHttpClient.GetAsync(new Uri("https://www.example.com/"));
// ...
}
}
}
只要您使用相同的名称,您就会得到一个在您的配置中使用 AddHttpClient
例程的客户端。
(请注意:此代码未经测试。它更像是一个指南)