Как настроить поток клиентских кредитов с помощью пользовательского интерфейса swagger и параметров решения проблемы перед запуском (CORS)

#asp.net-core #oauth #swagger

#asp.net-ядро #oauth #swagger

Вопрос:

У меня есть asp.net основное приложение, использующее библиотеку swagger

 <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
  

Я хотел бы разрешить разработчикам API, использующим веб-страницу / swagger, получать токен с помощью потока «ClientCredentials».
Я пробовал ниже, но получаю проблему с предполетной обработкой параметров

         c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                ClientCredentials = new OpenApiOAuthFlow
                {
                    TokenUrl = new Uri(baseAuthURL   "/oauth2/v2.0/token"),
                    Scopes = new Dictionary<string, string>
                    {
                        { "ABC/.default", "Access read operations" }
                    },
                    AuthorizationUrl = new Uri(baseAuthURL   "/oauth2/authorize")
                }
            }
        });
  

когда я нажимаю авторизовать

введите описание изображения здесь

После просмотра консоли я вижу вот что

Доступ к выборке в ‘https://login.microsoftonline.com/ABCD/oauth2/v2.0/token » из источника «https://localhost:44312 ‘ был заблокирован политикой CORS: на запрошенном ресурсе отсутствует заголовок ‘Access-Control-Allow-Origin’. Если непрозрачный ответ удовлетворяет вашим потребностям, установите режим запроса на «no-cors», чтобы получить ресурс с отключенным CORS.

Как я могу обойти эту проблему? Какие именно изменения необходимо внести в «AddSecurityDefinition», чтобы обойти эту проблему? Это то, что я даже могу обойти? (предполагая, что поставщик удостоверений может поддерживать запрос на предполетную проверку параметров)

Является ли единственным обходным путем для создания обратного прокси?

Как я могу расширить приведенный выше код для отправки пользовательских заголовков HTTP-запроса в запросе?

Я часами искал в Интернете пример того, как кто-то успешно использовал поток ClientCredentials для получения токена oauth в SwaggerUI.

Обновление 1: Что очень странно, так это то, что, несмотря на то, что запрос на предполетный запуск параметров получает ответ с заголовком access-control-allow-origin: * если я использую расширение Chrome для переопределения этого значения на точно такое же значение, это решает проблему. Очевидно, что это не решение, а скорее наблюдение. Очень странно, что установка значения, равного точно такому же значению, каким-то образом меняет результат.

Ниже приведена разница в заголовках ответов. Левая сторона без какого-либо расширения Chrome, правая сторона с расширением chrome, переопределяющим точно такое же значение. Вы можете видеть, что разницы нет. Итак, почему браузер может относиться к этому по-другому? введите описание изображения здесь

Я также попытался добавить прокси-сервер api авторизации с помощью AWS API Gateway, который вы можете увидеть в заголовках ответов, приведенных ниже. Это тоже не работает. введите описание изображения здесь

Комментарии:

1. Вам удалось это выяснить?

Ответ №1:

Я должен прочитать документацию NET Core CORS: https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1#preflight-requests-1

Браузеры не согласованы в том, как они устанавливают заголовки запросов управления доступом. Если либо:

  • Заголовки устанавливаются на что угодно, кроме «*»
  • Вызывается AllowAnyHeader: включите, по крайней мере, Accept, Content-Type и Origin, а также любые пользовательские заголовки, которые вы хотите поддерживать.

… и документы Swagger: https://swagger.io/docs/open-source-tools/swagger-ui/usage/cors /

В моем аналогичном случае мне пришлось включить CORS в API, используя эту конфигурацию (обратите внимание на заголовки):

         services.AddCors(options =>
        {
            options.AddPolicy(CorsPolicyName, configure =>
            {
                configure
                    .WithHeaders(
                       //Microsoft minimum set recommended 
                       "Accept", "Content-Type", "Origin", 
                       //Swagger headers
                       "api_key", "authorization", "x-requested-with" )
                    .WithOrigins(...);
            });
        });
  

Вы также можете разрешить любой заголовок, это компромисс между универсальным решением и экспозицией / безопасностью

Ответ №2:

Добавьте это в конфигурацию ваших служб при запуске:

 public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AnyOrigin", builder =>
        {
            builder =>                              
                builder.WithOrigins("https://login.microsoftonline.com")
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials());
        });
    });
}
  

Затем это для вашей конфигурации приложения:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env
{
    // after routing / mvc
    app.UseCors("AnyOrigin");
}
  

Обратите внимание, что вы отправляете заголовок авторизации, следовательно, запрос учетных данных, и это преобразуется в заголовок CORS для контроля доступа-разрешения-учетных данных. Конечная точка должна вернуть 200 OK, и это должно сработать.

Для получения дополнительной помощи по этому вопросу, связанному с SwaggerUI, ниже приведен полезный ресурс: https://swagger.io/docs/open-source-tools/swagger-ui/usage/cors /

Комментарии:

1. Не могли бы вы объяснить, как именно это решит проблему, описанную выше? Выше вы можете видеть, что предварительные запросы отправляются на отдельный URL, отличный от api..

2. Обновил мой ответ, чтобы он был более конкретным для вашего требования.

3. Вы не адресовали междоменный запрос параметров предполетной обработки другому домену.

4. Не могли бы вы подтвердить, что вы можете выполнить это при использовании двух разных доменов?

5. @jbooker можете ли вы решить эту проблему?