Проверка подлинности .NET Core Token - тело - PullRequest
2 голосов
/ 08 октября 2019

Мне нужно создать пользовательскую аутентификацию через JWT для .NET Core Web API, но требуется, чтобы клиенты хотели отправлять токен в теле HTTP-запроса.

Это не стандартный подходи не поддерживается .NET Core по умолчанию. Есть ли способ получить токен из тела HTTP-запроса и использовать его для аутентификации.

То, что у меня есть в настоящее время, зависит от Request.EnableRewind() и от использования MemoryStream для чтения из тела и последующего поисканачало тела снова, чтобы контроллер мог прочитать его позже. Это прекрасно работает, но если за короткий промежуток времени появятся тысячи запросов, производительность API снизится, и это нехорошо.

Есть ли хорошая альтернатива этому подходу?

services.AddJwtBearer(options =>
{
    options.RequireHttpsMetadata = true;
    options.SaveToken = true;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = false,
        ValidateAudience = false, 
        RequireExpirationTime = true,
        ClockSkew = TimeSpan.Zero
    };

    options.Events = new JwtBearerEvents
    {
        OnMessageReceived = ctx =>
        {
            StringValues values;

            if (ctx.Request.Method.Equals("POST"))
            {
                ctx.Request.EnableRewind();
                using (var ms = new MemoryStream())
                {
                    ctx.Request.Body.CopyTo(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    ctx.Request.Body.Seek(0, SeekOrigin.Begin);
                    using (var reader = new StreamReader(ms))
                    {
                        var jsonBody = reader.ReadToEnd();
                        var body = JsonConvert.DeserializeObject<BaseRequest>(jsonBody);
                        ctx.Token = body.Token;
                        ctx.Request.Headers["Authorization"] = $"Bearer {body.Token}";
                    }
                    return Task.CompletedTask;
                }
            }
            return Task.CompletedTask;
        }
    };
});

1 Ответ

1 голос
/ 09 октября 2019

Поскольку вы просили альтернативный подход к использованию MemoryStream, вы можете использовать Request.EnableBuffering(), возможно. Я бы предложил проверить " Перечитывание тела запросов ASP.Net Core с EnableBuffering () " на devblogs.microsoft.com ...

По сути, ваш OnMessageReceived будет выглядетькак-то так:

if (ctx.Request.Method.Equals("POST")
{
    ctx.Request.EnableBuffering();
    using (var reader = new StreamReader(ctx.Request.Body, Encoding.UTF8, true, $YOURBUFFERSIZE$, true))
    {
        var jsonBody = reader.ReadToEnd();
        var body = JsonConvert.DeserializeObject<BaseRequest>(jsonBody);
        if (body != null)
        {
            ctx.Token = body.Token;
            ctx.Request.Headers["Authorization"] = $"Bearer {body.Token}";
            ctx.Request.Body.Position = 0;
        }
    }
}

Честно говоря, это не самый лучший способ сделать это, но если вы действительно хотите избежать изменения чего-либо, кроме вашего OnMessageReceived, я думаю, этот метод не требуетиспользование MemoryStream.

...