NikFaraday
@NikFaraday
Student full-stack Developer

Как сделать редирект на refresh-token когда получаю AuthenticationFailed на asp.net core web api?

Здравствуйте

Уже настроена аутентификация на проекте asp.net core web api. Нужно сделать, что бы при истечении срока жизни access token делался redirect на refresh-token endpoint, но не могу понять как его вообще сделать. Вот часть конфигурации аутентификации:

.AddJwtBearer(options =>
{
    string securityKey = builder.Configuration.GetSection("JwtOptions:SecurityKey").Value;
    byte[] byteKey = Encoding.UTF8.GetBytes(securityKey);

    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = false,
        ValidateAudience = false,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(byteKey)
    };

    options.Events = new JwtBearerEvents()
    {
        OnMessageReceived = context =>
        {
            context.Token = context.Request.Cookies["access-token"];
            return Task.CompletedTask;
        },
        OnAuthenticationFailed = context =>
        {
            context.Response.Redirect("https://localhost:8876/api/v1.0/authentication/refresh-token");
            return Task.CompletedTask;
        },
        OnChallenge = context => // Это не нужно, но так тоже не работает
        {
            context.Response.Redirect("https://localhost:8876/api/v1.0/authentication/refresh-token");
            return Task.CompletedTask;
        }
    };
});


Когда получаю HttpStatusCode401, срабатывает событие OnAuthenticationFailed, но context.Response.Redirect() ничего не делает (Это не странно, он возвращает void). Тут вопрос, а как тогда сделать редирект на другой эндпоинт, что бы получить новый access token перед тем, как вернётся HttpStatusCode401 и вернуть нормальный StatusCode?
  • Вопрос задан
  • 274 просмотра
Решения вопроса 1
NikFaraday
@NikFaraday Автор вопроса
Student full-stack Developer
Решил. Как это всё делается? Внутрь onAuthenticationFailed вставляем этот код:
if (context.Exception?.GetType() == typeof(SecurityTokenExpiredException))
{
    IJwtService jwtService = context.HttpContext.RequestServices.GetService<IJwtService>();

    if (context.Request.Cookies.TryGetValue("refresh-token", out string refreshToken))
    {
        Result<ClaimsPrincipal> principalResult = jwtService.ValidateAndDecodeToken(refreshToken);
        if (!principalResult.IsSuccess || principalResult.Value == null)
        {
            return Task.CompletedTask;
        }

        Result<string> renewAccessTokenResult = jwtService.Encode(principalResult.Value);
        if (!renewAccessTokenResult.IsSuccess && renewAccessTokenResult.ValidationErrors.Any())
        {
            return Task.CompletedTask;
        }

        context.Response.Cookies.Append("access-token", renewAccessTokenResult.Value);
        context.Response.StatusCode = 200;
        context.HttpContext.User = principalResult.Value;
        context.Principal = principalResult.Value;
        context.Success();
    }
}
return Task.CompletedTask;


Т.е.. вызывает сервис, берём refresh token и из него извлекаем ClaimPrincipal, далее на его основе делаем access token из того же сервиса и обрабатываем запрос, что бы он возвращал нужный статус. Как говорил Andrei SunnyPh , это допустимая практика (Спасибо)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
yarosroman
@yarosroman
C# the best
Клиент сам должен следить за временем жизни токена и сам делать рефреш.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы