Как мне поддерживать несколько обработчиков токенов Bearer в одном действии? - PullRequest
0 голосов
/ 13 мая 2019

У меня есть приложение с существующей реализацией OAuth (вроде). Мы переходим на использование Identity Server для OAuth, и теперь мне нужно поддерживать обе схемы аутентификации на некоторых контроллерах / действиях.

Жетоны-носители для каждого метода Auth явно различны. Один из них - это guid, а другой - правильный токен, сгенерированный Identity Server.

Все, что мне нужно, это как-то посмотреть на токен и сказать что-либо с длиной строки <= 36 должно быть старым методом. Все остальное использовать Identity Server. </p>

Корневой контроллер имеет базовый атрибут [Authorize]. Также, если я переключу порядок схемы, первая из перечисленных работ.

Вот мой код Startup.cs

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = Constants.CompanyBearerScheme;
            options.DefaultChallengeScheme = Constants.CompanyBearerScheme;
        }).AddJwtBearer(options =>
        {
            options.Authority = "https://identityserverurl";
            options.Audience = "APISCOPE";
            options.RequireHttpsMetadata = true;
        }).AddBearerToken(Constants.CompanyBearerScheme, o =>
        {
            o.ConnectionString = bearerTokenHandlerOptions.ConnectionString;
            o.DefaultScopes = bearerTokenHandlerOptions.DefaultScopes;
        })

Пример действия

    [Authorize(AuthenticationSchemes = "CompanyBearer,Bearer")]
    [HttpGet("TEST")]
    public async Task<IActionResult> TestAuthentication()
    {
    return Ok();
    }

Пример запроса

GET {{Url}}/Api/TEST
Authorization: Bearer SOMETOKEN

1 Ответ

0 голосов
/ 23 мая 2019

Я понял.

Нужно использовать собственную схему политики для сравнения входящего запроса.

 services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = Constants.DefaultSelectorPolicy;
            options.DefaultChallengeScheme = Constants.DefaultSelectorPolicy;
        })
        .AddPolicyScheme(Constants.DefaultSelectorPolicy, Constants.DefaultSelectorPolicy, options =>
        {
            options.ForwardDefaultSelector = ctx =>
            {
                if (!ctx.Request.Headers.ContainsKey("Authorization"))
                {
                    return null;
                }

                var authorizationHeader = ctx.Request.Headers["Authorization"];

                var authorization = AuthenticationHeaderValue.Parse(authorizationHeader);

                if (authorization.Scheme.ToLower() != "bearer")
                {
                    return null;
                }

                if (authorization.Parameter.Length > 36)
                {
                    return "Bearer";
                }

                return Constants.CompanyBearerScheme;
            };
        })
...