如何在每个请求中传递授权令牌

时间:2021-03-14 02:00:40

标签: asp.net-core .net-core asp.net-core-webapi

用户登录后,我验证他们的信息并生成 JWT 令牌。

身份验证过程发生在 var statusPublisher: AnyPublisher<Status, Never> { $substatus1 .combineLatest($substatus2) .map { s1, s2 -> Status in ... } .eraseToAnyPublisher() } (它不是我的自定义处理程序)。

我在哪里以及如何保存这个令牌,以便它会随着 http 调用发送?由于 XSS 攻击,我不想将其保存在客户端。以下似乎也不起作用,因为我不会出现在每个请求中

Authentication

我找到了使用 HttpContext.Request.Headers.Append("Authorization", MyGeneratedJWTTokenAsString); 的答案,但还有其他安全的方法吗?

1 个答案:

答案 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 例程的客户端。

(请注意:此代码未经测试。它更像是一个指南)