Изменить код ответа из проверки OpenIdDict, если токен отсутствует - PullRequest
1 голос
/ 09 марта 2020

У меня есть аутентификация токена на предъявителя, работающая с OpenIddict 3.0. Когда клиент обращается к авторизованному контроллеру с отсутствующим токеном, я хочу, чтобы он возвратил код ошибки 401 Несанкционированный, а не 400 Плохой запрос.

Это то, откуда приходит сообщение об ошибке, но откуда берется код состояния http и как я переопределил бы это?

OpenIddictValidationHandlers.cs

public ValueTask HandleAsync([NotNull] ProcessAuthenticationContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException(nameof(context));
    }
    if (string.IsNullOrEmpty(context.Request.AccessToken))
    {
        context.Logger.LogError("The request was rejected because the access token was missing.");
        context.Reject(
            error: Errors.InvalidRequest,
            description: "The access token is missing.");
        return default;
    }
    context.Token = context.Request.AccessToken;
    return default;
}

И мои Startup.cs

...
var openId = services.AddOpenIddict()
...
    .AddValidation(config =>
    {
        config.UseLocalServer();
        config.UseAspNetCore();
    });

1 Ответ

1 голос
/ 13 марта 2020

Спасибо за сообщение об этой проблеме, которая была исправлена ​​в версии 3.0.0-alpha1.20163.83: OpenIddict теперь будет возвращать ошибку 401 для запросов, отклоненных из-за отсутствующего маркера доступа.

Обработчик событий, отвечающий за выбор соответствующего Код состояния HTTP: OpenIddict.Validation.AspNetCore:

/// <summary>
/// Contains the logic responsible of attaching an appropriate HTTP status code.
/// Note: this handler is not used when the OpenID Connect request is not initially handled by ASP.NET Core.
/// </summary>
public class AttachHttpResponseCode<TContext> : IOpenIddictValidationHandler<TContext> where TContext : BaseRequestContex
{
    /// <summary>
    /// Gets the default descriptor definition assigned to this handler.
    /// </summary>
    public static OpenIddictValidationHandlerDescriptor Descriptor { get; }
        = OpenIddictValidationHandlerDescriptor.CreateBuilder<TContext>()
            .AddFilter<RequireHttpRequest>()
            .UseSingletonHandler<AttachHttpResponseCode<TContext>>()
            .SetOrder(AttachCacheControlHeader<TContext>.Descriptor.Order - 1_000)
            .Build();

    /// <summary>
    /// Processes the event.
    /// </summary>
    /// <param name="context">The context associated with the event to process.</param>
    /// <returns>
    /// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation.
    /// </returns>
    public ValueTask HandleAsync([NotNull] TContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (context.Response == null)
        {
            throw new InvalidOperationException("This handler cannot be invoked without a response attached.");
        }

        // This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved,
        // this may indicate that the request was incorrectly processed by another server stack.
        var response = context.Transaction.GetHttpRequest()?.HttpContext.Response;
        if (response == null)
        {
            throw new InvalidOperationException("The ASP.NET Core HTTP request cannot be resolved.");
        }

        response.StatusCode = context.Response.Error switch
        {
            null => 200,

            Errors.InvalidToken => 401,
            Errors.MissingToken => 401,

            Errors.InsufficientAccess => 403,
            Errors.InsufficientScope  => 403,

            _ => 400
        };

        return default;
    }
}
...