Руководство OpenAPI Шаг 6 Объект “security” | learnapidoc-ru

Introduction

As is described in the previous article, Swagger Documentation is a handy tool that generates documentation in a friendly manner from an XML file generated by the .NET Framework. But what if the described API has authentication, then the documentation should have it too.

The Swagger Documentation web interface will act as a REST Client, by sending a request to the Authentication endpoint, receiving the Bearer Authentication Token, and then, with this token, we’ll have to put it into an input box in order to set the authentication header for the next requests that we’ll be making.

Описание api

Для описания нашего API будем использовать спецификацию OpenAPI 3.0 и Swagger — YAML-файл, который описывает все схемы данных и все эндпоинты. По нему очень легко ориентироваться, у него приятный интерфейс. Но описывать вручную всё очень муторно, поэтому лучше генерировать его кодом.

Adding the security requirement

The AddSecurityRequirement extension method will add an authorization header to each endpoint when the request is sent. This method takes a dictionary of type Dictionary as a parameter, because the endpoints can have different authentication types (e.g. Basic, Saml).

The parameters above are required to setup the Security Requirement, but there are more. So Microsoft did a great job by defining all these fields and properties on the OpenAPI.NET GitHub page [2] [3].

I. create and setup a new asp.net core web api

  1. First, create your ASP.NET Core Web API. To do that just follow the steps below.

2. Now we need to install required packages for this project. I have listed it all below.

  • Dapper
  • Microsoft.EntityFrameworkCore.SqlServer.Design
  • Microsoft.AspNetCore.Authentication.JwtBearer
  • Swashbuckle.AspNetCore
  • Swashbuckle.AspNetCore.Swagger
  • Swashbuckle.Core
  • System.IdentityModel.Tokens.Jwt
Похожее:  HTTPS для разработчиков | Techrocks

Use NuGet Package Manager to install this package. If this is your first time using this, you can visit this article.

Ii. setup appsettings.json

After installing all the necessary packages that we need, add your SQL connection string and JWT Auth key inside appsettings.json.

Iii. register jwt base authentication

First, we need to configure JWT based authentication in our project. To do that, register JWT authentication on your startup.cs. Put the code snippet below under ConfigureServices.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)    
            .AddJwtBearer(options =>    
            {    
                options.TokenValidationParameters = new TokenValidationParameters    
                {    
                    ValidateIssuer = true,    
                    ValidateAudience = true,    
                    ValidateLifetime = true,    
                    ValidateIssuerSigningKey = true,    
                    ValidIssuer = Configuration["JwtAuth:Issuer"],    
                    ValidAudience = Configuration["JwtAuth:Issuer"],    
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtAuth:Key"]))    
                };    
            });
  • ValidateIssuer = true » Validate the server that generates the token.
  • ValidateAudience = true » Validate the recipient of the token is authorized to receive.
  • ValidateLifetime = true » Check if the token is not expired and the signing key of the issuer is valid
  • ValidateIssuerSigningKey = true » Validate signature of the token
  • ValidIssuer » stored in appsettings.json
  • ValidAudience » stored in appsettings.json
  • IssuerSigningKey » stored in appsettings.json

Iv. create model properties

Let’s create model properties for this project. We will use this model later to handle request parameters and response in our web API. See the code snippet below.

LoginModel

This model will handle the parameter request for our API login method.

Openapi specification — swagger authentication

Step 1: OpenAPI Specification Maven Dependency

There is no additional dependency required to setup Authentication in Swagger. The latest version of springdoc-openapi-uican be found on Maven Central. To add it to our Maven project, we need to add the dependency in the pom.xml

Dependency for springdoc-openapi-ui

Step 2: Swagger Configuration with SpringBoot

The configuration of Swagger3 requires the OpenAPI bean. License and Contact information can also be added using OpenAPI bean. For Authentication, we have to call addSecurityItem(SecurityRequirement securityItem)which adds the message in Authorize modal. We also add the component for the necessary Security Schema. Security Schema would consist of schema name, type, scheme and other details.

In our case we are using Bearer Token using JWT token. Below is our swagger configuration:

Swagger Configuration using Bearer Authentication

Step 3: The Authorize button : Run the application

Authorize button

Just with this earlier code change, Swagger will now show the “Authorize” button in top right corner.

We have not written any code for actual authentication, but yes swagger UI changes are complete. When we click Authorize button, below modal should pop up where we can add token and Authorize the APIs. Now you can invoke the APIs as before.

Input screen for Swagger Authorisation Token

Step 4: Let’s modify the code to validate the token

So, we are not going to do the complete implementation to validate a JWT token. However, we will try to generate JWT token and pass them in our request.

Let’s look at the code below to examine what altered !!

Secured HTTP Post endpoint to create Employee

As we can see, we have added a couple of things to our existing code

  1. We have an additional ApiResponse for HttpStatus code 401 to indicate an unauthorized user request due to token verification failure.
  2. We added HttpServletRequest parameter to read the servlet request.
  3. Try-catch block is added to catch authentication failure and return response with 401 HttpStatus code
  4. I have also added additional service class which validates the token, else throws Authentication Exception incase of an invalid token. This token is extracted from the HttpServletRequest header. httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION)

Step 5: Authentication in action

We have previously seen how to use theAuthorize button. The token is applied to all the API headers when a request is sent. We will look at creating a new employee record. Other APIs function in a similar fashion.

Request: We have added the token and the request body.

Swagger Post Request with Token Authentication

Response: We can see that token is assigned in the request header for the curl request generated by swagger.

You can try to see what happens when you do not set the token.

Swagger Post Response with Token Authentication

Step 6: Voila. We are done!! It’s your time to test

Swagger “Try it out

If you have downloaded the sample code on your local machine, compiled it, and ran it, you might have loaded the Swagger UI in your favorite browser.

To run the swagger, after you run the SpringBoot application, you can hit the URL:

http://localhost:10001/open-api-demo/swagger-ui.html

As a guide to download the code, compile and/or run, refer to the README.md file in the sample code root directory. If you are still not able to make it work, drop me a comment or a note. We can dig in together to make it work. Afterall, getting your hands dirty will help you understand it easily.

I assume you have the sample code running just fine on your system. Swagger has a built-in “Authorize” & “Try it out” button against each API, which has the capability to run request so that the consumer can validate the output. It also shows the request that was sent with the authorisation headers and other parameters.

Thus, when you try to execute a request, Swagger UI will read the definition of the request and expect the consumer to provide the test data if relevant, such as a path/query parameter or a request body. Once data is provided, the consumer can hit Executebutton which runs the request and its response is returned.

We have thus updated our SpringBoot application with OAuth Token. We added Swagger dependency and the necessary OpenAPI Specification configuration necessary for Authentication.

Thus our journey to add authentication to Swagger UI for API Documentation has come to an end.

Until next time Sayonaraya… Keep coding… Keep Learning… Keep Sharing…

Feel free to use comments to let me know what you liked or what you did not. I would definitely look forward for your suggestions and feedback on how this could have been better.

Swagger

Относится к инструментам API, связанным со спецификацией OpenAPI. Некоторыми из этих инструментов являются Swagger Editor, Swagger UI, Swagger Codegen, SwaggerHub и другие. Всеми инструментами управляет компания Smartbear.

Для получения дополнительной информации см. Инструменты Swagger. «Swagger» являлся изначально оригинальным названием спецификации OpenAPI, но позже имя было изменено на OpenAPI, чтобы усилить открытый, не лицензионный характер стандарта.

Люди иногда ссылаются на оба имени взаимозаменяемо (особенно на старых веб-страницах), но «OpenAPI» – это то, как следует обращаться к спецификации. Дополнительные сведения о разнице между OpenAPI и Swagger см. В разделе «В чем разница между Swagger и OpenAPI?».

Swagger editor

Онлайн-редактор, который проверяет документацию OpenAPI на соответствие правилам спецификации OpenAPI. Редактор Swagger помечает ошибки и дает советы по форматированию.

Swagger ui

Веб-фрэймворк (на GitHub), который анализирует документ в спецификации OpenAPI и создает веб-страницу интерактивной документации. Swagger UI – это инструмент, который превращает спецификацию в подобный Petstore-сайт.

V. create table and stored procedures

Let’s create a database, table, and stored procedure that we need for this tutorial. Below are the table and procedures that we need.

  1. Create a database using the query below.
CREATE DATABASE JWTDemoDB;

Vi. create repository class

The repository class will handle the authentication and CRUD functionality of our WEB API. This repository class will inherit from an interface class. To create this class, follow the steps below.

  1. Create a Repository Folder from your project’s root directory.
  2. Create New Interface and name it IJWTAuthManager. See the code snippet below.

What is <t>?

T is called a type parameter, which can be used as a type of fields, properties, method parameters, return types, and delegates in the DataStore class. For example, Data is generic property because we have used a type parameter T as its type instead of the specific data type.

What is swagger?

Swagger is an open-source set of rules, specifications, and tools for developing and describing RESTful APIs. The Swagger framework allows developers to create interactive, machine, and human-readable API documentation. Below is the swagger UI with our default methods and properties or this tutorial.

Swagger Dashboard - Use JWT Bearer Authorization in Swagger OpenAPI
Swagger

Before we start please make sure you have the following installed on your machine.

  • The latest version of Visual Studio
  • Alternatively, you can also use the Visual Studio Code.
  • SQL Server

In this tutorial, I am going to use Visual Studio 2022. Below is the video from my previous article on how to implement JWT Auth in ASP.NET Core.

Авторизация api ключом

В примере API OpenWeatherMap, который мы используем в этом курсе, используется ключ API, переданный в строке запроса URL-адреса (а не в заголовке). Если вы отправляете запрос без ключа API в строке запроса (или без действительного ключа API), сервер отклоняет запрос. Для получения подробной информации о модели авторизации OpenWeatherMap см. How to start.

Авторизация запроса

Прежде чем делать какие-либо запросы, нужна авторизация. Нажимаем кнопку Authorize и заполняем информацию, требуемую в окне «Авторизация», изображенном ниже:

Пример Petstore имеет модель безопасности OAuth 2.0. Код авторизации только для демонстрационных целей. Нет никакой реальной логики авторизации этих запросов, поэтому просто закрываем окно Авторизации.

Встраивание swagger ui в существующий сайт

Помимо публикации выходных данных пользовательского интерфейса Swagger в качестве отдельного сайта, можно встраивать файл Swagger в существующий сайт. Описание можно посмотреть здесь:

Swagger UI адаптивен и хорошо масштабируется, что позволяет вписать его практически в любое пространство. Тем не менее, встроенный в существующий сайт Swagger выглядит как сайт внутри сайта.

Go next ➡

Выбор схемы безопасности

В API REST могут использоваться различные подходы безопасности для авторизации запросов. Рассмотрим наиболее распространенные методы авторизации в Требованиях аутентификации и авторизации. Swagger UI поддерживает четыре схемы авторизации:

На этом шаге руководства по OpenAPI мы будем использовать подход с использованием API ключа, поскольку именно его использует API-интерфейс OpenWeatherMap. Если ваш API использует OAuth 2.0 или другой метод, надо прочитать Security Scheme information, чтобы узнать, как ее настроить. Тем не менее, все методы безопасности в основном следуют одному и тому же шаблону.

Знакомство со swagger при помощи petstore

Чтобы лучше понять интерфейс Swagger, давайте рассмотрим пример Swagger Petstore. В примере Petstore сайт генерируется с помощью Swagger UI.

Конечные точки сгруппированы следующим образом:

Конфигурация параметров swagger ui

Swagger UI предоставляет различные параметры конфигурации (не связанные с параметрами OpenAPI), которые можно использовать для настройки интерактивного дисплея. Например, можно указать, будет ли каждая конечная точка развернута или свернута, как будут сортироваться теги и операции, показывать ли заголовки запросов в ответе, включать ли раздел «Модели» после списка конечных точек и многое другое.

В этом руководстве не будем вдаваться в подробности этих параметров конфигурации.

Если посмотреть на код демонстрации пользовательского интерфейса Swagger (перейдите в View> Source), то увидим параметры, перечисленные в разделе // Build a system:

Все параметры (например, deepLinking, dom_id и т. Д.) являются значениями по умолчанию. Добавлен defaultModelsExpandDepth: -1, чтобы скрыть раздел «Модели» в нижней части экрана Swagger UI.

О параметрах конфигурации Swagger UI можете узнать в документации Swagger.

Обзор swagger ui

Swagger UI – один из самых популярных инструментов для создания интерактивной документации. Swagger UI создает интерактивную консоль API для экспериментов с запросами в реальном времени. Кроме того, Swagger UI (активно управляемый проект с лицензией Apache 2.0) поддерживает последнюю версию спецификации OpenAPI (3.x) и интегрируется с другими инструментами Swagger.

Прежде чем мы углубимся в Swagger, нужно прояснить ключевые термины.

Объект security

На корневом уровне документа OpenAPI добавим объект security, который определяет глобальный метод безопасности API:

app_id – произвольное имя, которое мы дали этой схеме безопасности в нашем объекте securitySchemes. Мы могли бы назвать ее как угодно.

Все пути будут использовать метод безопасности app_id по умолчанию, если он не переопределен значением на уровне объекта path. Например, на уровне пути мы могли бы перезаписать метод глобальной безопасности следующим образом:

Тогда путь weather будет использовать метод безопасности some_other_key, в то время как все другие пути будут использовать глобально объявленную безопасность app_id.

Определение эндпоинтов

Для страниц авторизации и регистрации нам нужны эндпоинты аутентификации и регистрации соответственно. В качестве аутентификации и сессий пользователя мы будем использовать JWT. Что это такое и как работает, разберём чуть позднее. Пока просто запомните эти 3 буквы.

Для страницы списка заметок нам нужны эндпоинты /api/categories для получения древовидного списка категорий и //notes?category_id=? для получения списка заметок текущей категории. Перемещаясь по другим категориям, мы будем отдельно запрашивать заметки для выбранной категории, а на фронтенде сделаем кэш на клиенте.

Отображение в swagger ui

В редакторе Swagger, если еще не указано, добавим объект security на корневом уровне:

И вставим объект securitySchemes в объект components (на том же уровне, что и parameters и responses):

И проверим, как изменился наш Swagger UI в правой части: появилась кнопка Authorize

Authorize
Добавление в спецификацию информации о безопасности

Если нажать на кнопку, то появится description и другие детали авторизации:

После ввода ключа API (Ключ мы получали во втором модуле ) и нажатия кнопки Authorize метод авторизации устанавливается для любого количества запросов. Сессия авторизации истекает только тогда, когда пользователи обновляют страницу.

Примеры сайтов с документаций по swagger ui

Прежде чем мы перейдем к другому API с этим пособием по Swagger (кроме демонстрации Petstore), посмотрим на другие реализации Swagger:

Некоторые из этих сайтов выглядят одинаково, но другие, такие как The Movie Database API и Zomato, были легко интегрированы в остальную часть их сайта документации.

Глядя на примеры, можно заметить краткость документации в реализации Swagger. Эта краткость объясняется тем, что дисплей Swagger предназначен для интерактивного взаимодействия, где можно опробовать вызовы и посмотреть ответы – используя свой собственный ключ API, чтобы увидеть свои собственные данные. такой подход получил название: «учись, практикуясь».

Проблема cors

Если безопасность правильно настроена, но запросы отклоняются, это может быть связано с проблемой CORS (cross-origin resource sharing). CORS – это мера безопасности, которую веб-сайты внедряют, чтобы другие сценарии и процессы не могли получать свое содержимое через запросы от удаленных серверов. Подробности см. В разделе «Поддержка CORS» в документации по интерфейсу Swagger.

Если запросы не работают, переходим в консоль JavaScript браузера (в Chrome, View> Developer> Javascript Console), делаем запрос, и смотрим, относится ли ошибка к запросам разных источников. Если это так, можно попросить разработчиков включить CORS на конечных точках.

Проблемы swagger ui

Изучая интерфейс Swagger, можно заметить несколько ограничений:

Проверка создания питомца

  1. Разворачиваем точку GET /pet/{petId}
  2. Нажимаем кнопку Try it out
  3. Вводим ID питомца, который использовали в предыдущей операции. (Если забыли ID, посмотрите на конечную точку POST Pet, чтобы проверить значение.)
  4. Нажимаем Execute . В ответе мы должны увидеть имя нашего питомца.

Прототипирование

Начнём с макетов интерфейса. Нам нужно понять, какие ручки будут у нашего API и какой состав данных он должен отдавать. Макеты мы будем делать, чтобы понять, какие сущности, поля и эндпоинты нам нужны. Используем для этого онлайн-сервис NinjaMock. Он подходит, если макет надо сделать быстро и без лишних действий.

Страницу регистрации сделаем простую, с четырьмя полями: Name, Email, Password и Repeat Password. Лейблы делать не будем, обойдемся плейсходерами. Авторизацию сделаем по юзернейму и паролю.

После входа в приложение пользователь увидит список заметок, который будет выглядеть примерно так:

  • Слева — список категорий любой вложенности.
  • Справа — список заметок в виде карточек, который делится на два списка: прикреплённые и обычные карточки.
  • Каждая карточка состоит из заголовка, который урезается, если он очень длинный.
  • Справа указано, сколько секунд/минут/часов/дней назад была создана заметка.
  • Тело заголовка — отрендеренный Markdown.
  • Панель инструментов. Через неё можно изменить цвет, прикрепить или удалить заметку.

Тут важно отметить, что файлы заметки мы не отображаем и не будем запрашивать у API для списка заметок.

Работа с json web token

JSON Web Token (JWT) — это JSON-объект, который определён в открытом стандарте RFC 7519. Он считается одним из безопасных способов передачи информации между двумя участниками. Для его создания необходимо определить заголовок (header) с общей информацией по токену, полезные данные (payload), такие как id пользователя, его роль и т.д., а также подписи (signature).

JWT использует преимущества подхода цифровой подписи JWS (Signature) и кодирования JWE (Encrypting). Подпись не даёт кому-то подделать токен без информации о секретном ключе, а кодирование защищает от прочтения данных третьими лицами. Давайте разберёмся, как они могут нам помочь для аутентификации и авторизации пользователя.

Другими словами, аутентификация проверяет легальность пользователя. Пользователь становится авторизированным, если может выполнять разрешённые действия.

Важно понимать, что использование JWT не скрывает и не маскирует данные автоматически. Причина использования JWT — проверка, что отправленные данные были действительно отправлены авторизованным источником. Данные внутри JWT закодированы и подписаны, но не зашифрованы.

Разработка сервиса

Писать будем на Golang.

  1. Идём на официальный сайт.
  2. Копируем ссылку до архива, скачиваем, проверяем хеш-сумму.
  3. Распаковываем и добавляем в переменную PATH путь до бинарников Golang
  4. Пишем небольшой тест проверки работоспособности, собираем бинарник и запускаем.

Теперь создаём проект. Структура стандартная:

  • build — для сборок,
  • cmd — точка входа в приложение,
  • internal — внутренняя бизнес-логика приложения,
  • pkg — для кода, который можно переиспользовать из проекта в проект.

Исходники проекта — в репозитории на GitHub.

Я очень люблю логировать ход работы приложения, поэтому перенесу свою обёртку над логером logrus из другого проекта. Основная функция здесь Init, которая создает логер, папку logs и в ней файл all.log со всеми логами. Кроме файла логи будут выводиться в STDOUT.

APIService будет работать на сокете. Создаём роутер, затем файл с сокетом и начинаем его слушать. Также мы хотим перехватывать от системы сигналы завершения работы. Например, если кто-то пошлёт приложения сигнал SIGHUP, приложение должно корректно завершиться, закрыв все текущие соединения и сессии.

Теперь давайте добавим сразу стандартный handler для метрик. Я его копирую в директорию pkg, далее добавляю в роутер. Все последующие роутеры будем добавлять так же.

Далее создаём точку входа в приложение. В  директории cmd создаём директорию main, а в ней — файл app.go. В нём мы создаём функцию main, в которой инициализируем и создаём логер. Роутер создаём через ключевое слово defer, чтобы метод Init у роутера вызвался только тогда, когда завершится функция main.

Но для разработки нам нужно запускать приложение на порту, а не на сокете. Поэтому давайте добавим запуск приложения на порту в наш роутер. Определять, как запускать приложение, мы будем с помощью конфига.

Создадим для приложения контекст. Сделаем его синглтоном при помощи механизма sync.Once. Пока что в нём будет только конфиг. Контекст в виде синглтона создаю исключительно в учебных целях, впоследствии он будет выпилен. В большинстве случаев синглтоны — необходимое зло, в нашем проекте они не нужны. Далее создаём конфиг. Это будет YAML-файл, который мы будем парсить в структуру.

В роутере мы вытаскиваем из контекста конфиг и на основании listen.type либо создаем сокет, либо вешаем приложение на порт. Код graceful shutdown выделяем в отдельный пакет и передаём на вход список сигналов и список интерфейсов io.Close, которые надо закрывать.

Ссылка на схему безопасности в компонентах

В объекте components добавим объект securitySchemes, который определяет подробности о схеме безопасности, которую использует API:

Свойства, которые можно использовать для каждого элемента в объекте securitySchemes, включают следующее:

Тест авторизации

Теперь, когда мы добавили авторизацию, попробуем сделать фактический запрос API. В редакторе Swagger (правая панель) нажмите кнопку Authorize, вставляем образец ключа API, показанного в описании, в поле Value (или используйте свой собственный ключ API OpenWeatherMap) и нажимаем Authorize. После чего кликаем Close , чтобы закрыть окно авторизации.

В разделе «Current Weather Data» разворачиваем конечную точку погоды GET и кликаем Try it out. В поле почтовый индекс введем свой почтовый индекс и сокращение страны (например, 95050, США), а затем нажмите Execute.

При выполнении запроса, Swagger UI показывает отправленный запрос. Например, после выполнения запроса погоды, curl выглядит следующим образом:

&Appid = fd4698c940c6d1da602a70ac34f0b147 “указывает, что ключ API включается в строку запроса, поэтому запрос будет авторизован. Если вы скопируете отправленный curl и вставите его в командную строку, вы увидите успешный ответ:

response
Успешный curl response

Ответ сервера также отображается непосредственно в Swagger UI со ссылкой для его загрузки:

{"coord":{"lon":-121.96,"lat":37.35},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"},{"id":701,"main":"Mist","description":"mist","icon":"50d"}],"base":"stations","main":{"temp":55.24,"pressure":1012,"humidity":77,"temp_min":51.08,"temp_max":59},"visibility":16093,"wind":{"speed":5.82,"deg":320},"rain":{"1h":0.25},"clouds":{"all":40},"dt":1544039760,"sys":{"type":1,"id":5122,"message":0.0052,"country":"US","sunrise":1544022470,"sunset":1544057391},"id":420006397,"name":"Santa Clara","cod":200}

Обратите внимание, если вы обнаружите при реализации Swagger UI, что запрос curl работает? но ответ не отображается в Swagger UI, может возникнуть проблема CORS с вашими запросами на блокировку API от веб-приложений, таких как Swagger. Подробнее см. Troubleshooting issues with Swagger UI.

Go next ➡

Устранение неполадок

При настройке Swagger UI, могут возникать проблемы. Следующие проблемы являются наиболее распространенными:

👨‍💻 практическое занятие: создание спецификации openapi в swagger ui

На этом занятии мы создадим документацию в Swagger UI в спецификации OpenAPI. Если вы используете один из предварительно созданных файлов OpenAPI, вы можете увидеть демонстрацию того, что мы создадим здесь: OpenWeatherMap Swagger UI или Sunrise/sunset Swagger UI).

Для интеграции спецификации OpenAPI в Swagger UI:

Единственная папка, с которой мы будем работать в загруженном zip-архиве, – это папка dist (сокращение от дистрибутива). Все остальное используется, только если мы перекомпилируем файлы Swagger, что выходит за рамки этого руководства.

или

Adding the security definition

By specifying the security definition, Swagger will take into account that it will have to add the authorization feature. This feature consists of an “Authorize” button at the top of the page that will set the authorization header. The following code will be added in the AddSwaggerGen extension method of the SwaggerGen package.

This five parameters are required in order to define how the security key will act.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *