JWT BearerHandler Token Falsed, но запрос все еще обрабатывается - PullRequest
0 голосов
/ 02 июля 2019

У меня возникла очень странная проблема, и я предполагаю, что мне чего-то не хватает в моей настройке.

У меня есть WebAPI, который защищен IdentityServer4.Это только использование Client_credentials.Если я напишу неправильный ClientId или ClientSecret, то этот пользователь не аутентифицирован, и я не могу подключиться к своему WebAPI.Но если я пишу неправильное имя области действия, запрос все еще обрабатывается, и я получаю ответ обратно, странная часть заключается в том, что выдается исключение, но по какой-то причине оно игнорируется .NET Core Framework.

ЗдесьНекоторая отладочная информация из моего окна выводавыдается исключение, которое говорит о том, что токен не проверен, запрос все еще может продолжаться и выполняться, и ответ отправляется обратно клиенту.

Вот так выглядит ConfigureServices:

    services
        .AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.Authority = "https://localhost:44392/";
            options.Audience = "FAKE_SCOPE";
        });

И методы Configure ()

    app.UseAuthentication();
    app.UseMvc();

Вот так выглядит токен JWT:

{
  "nbf": 1562062882,
  "exp": 1562066482,
  "iss": "https://localhost:44392",
  "aud": [
    "https://localhost:44392/resources",
    "bookingApi"
  ],
  "client_id": "clientId",
  "scope": [
    "bookingApi"
  ]
}

И это код клиента, вызывающий API.

        var idpUrl = "https://localhost:44392/";    
        var clientId = "clientId";
        var clientSecret = "secret";
        var scope = "bookingApi";

        var accessToken = await GetAccessTokenAsync(new Uri(idpUrl), clientId, clientSecret, scope);
        string content = await GetContent(new Uri("https://localhost:44360/v1/bookings"), accessToken);

Наверное, я что-то упустил, когда дело доходит до авторизации, я пробовал разные

services.Authorization()

В методах ConfigureServices (), но это не помогает, думаю, я написал это неправильно.

С наилучшими пожеланиями Магнус

1 Ответ

0 голосов
/ 03 июля 2019

Проведя день, пытаясь выяснить, почему он не работает, я решил пошагово пройти код Microsoft и обнаружил его в AuthenticationMiddleware.

открытый класс AuthenticationMiddleware {private readonly RequestDelegate _next;

public AuthenticationMiddleware(RequestDelegate next, IAuthenticationSchemeProvider schemes)
{
    if (next == null)
    {
        throw new ArgumentNullException(nameof(next));
    }
    if (schemes == null)
    {
        throw new ArgumentNullException(nameof(schemes));
    }

    _next = next;
    Schemes = schemes;
}

public IAuthenticationSchemeProvider Schemes { get; set; }

public async Task Invoke(HttpContext context)
{
    context.Features.Set<IAuthenticationFeature>(new AuthenticationFeature
    {
        OriginalPath = context.Request.Path,
        OriginalPathBase = context.Request.PathBase
    });

    // Give any IAuthenticationRequestHandler schemes a chance to handle the request
    var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
    foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
    {
        var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
        if (handler != null && await handler.HandleRequestAsync())
        {
            return;
        }
    }

    var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
    if (defaultAuthenticate != null)
    {
        var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
        if (result?.Principal != null)
        {
            context.User = result.Principal;
        }
    }

    await _next(context);
}

}

И в основном происходит то, что у результата есть свойства Failure, которые содержат мое исключение аутентификации, но, поскольку в коде нет проверки для этого, он продолжит запроск следующему промежуточному программному обеспечению в конвейере.Поэтому я в основном написал свой собственный AuthenticationMiddleware, добавив проверку, имеет ли Failure значение, и возвращает 403.

        var defaultAuthenticate = await _schemas.GetDefaultAuthenticateSchemeAsync();
        if (defaultAuthenticate != null)
        {
            var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
            if (result?.Principal != null)
                context.User = result.Principal;

            if (result?.Failure != null)
                throw new AuthorizationException(result.Failure.Message);
        }

        await _next(context);
    }
    catch (AuthorizationException ex) when (!context.Response.HasStarted)
    {
        _logger.LogWarning(ex, "Unauthorized access encountered.");

        context.Response.Clear();
        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
    }

Это, однако, не то, что нужно делать, кроме меня, так что если кто-то знает, почему мне нужно это сделатьБуду рад за информацию.

...