Что такое JWT?

JSON Web Token (JWT) — это открытый стандарт, который определяет передачу данных между двумя сторонами как объект в кодировке JSON, содержащий набор утверждений. Они могут быть подписаны либо парой открытого/закрытого ключей, либо секретом, известным двум обменивающимся сторонам для проверки их подлинности, и, таким образом, считаются безопасными.

JWT в веб-API .NET

JWT обычно используются для защиты API, и в каждом современном языке программирования существуют библиотеки для работы с ними. В .NET пакет Microsoft.AspNetCore.Authentication.JwtBearer содержит промежуточное ПО, которое выполняет за нас большую часть работы.

Демо-проект

Эта статья сопровождается примером проекта, который можно найти здесь: https://github.com/smittix6/JwtAuthentication.

Шаг 1 – Добавьте базовую аутентификацию JWT

Сначала вам нужно добавить пакет NuGet Microsoft.AspNetCore.Authentication.JwtBearer в свой проект. Обратитесь к Документации Microsoft, если вы не знакомы с этим процессом.

Добавьте следующую строку в раздел запуска вашего приложения (в Program.cs для этого проекта).

builder.Services.AddAuthentication("Bearer").AddJwtBearer();

Ограничьте доступ к контроллеру (или действию) с помощью атрибута [Authorize].

[ApiController]
[Authorize]
[Route("[controller]")]

Вашему контроллеру теперь требуется действительный токен JWT для аутентификации!

Шаг 2. Создайте JWT и проверьте аутентификацию

В Интернете доступно множество сервисов (и примеров кода) для генерации токенов JWT, и я настоятельно рекомендую вам изучить их и определить, что подходит для вашего приложения, но в этом руководстве мы будем использовать инструмент, входящий в состав .NET SDK. называется user-jwts для генерации наших JWT.

Откройте командную строку и перейдите в каталог, в котором находится ваш проект.

cd repos\JwtAuthentication\JwtAuthentication

Теперь запустите команду, чтобы создать JWT для локального использования:

dotnet user-jwts create

Это вернет следующее:

New JWT saved with ID 'fbb69945'.
Name: chris                                                                                                             
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImNocmlzIiwic3ViIjoiY2hyaXMiLCJqdGkiOiJmYmI2OTk0NSIsImF1ZCI6WyJodHRwOi8vbG9jYWxob3N0OjQxNDQiLCJodHRwczovL2xvY2FsaG9zdDo0NDMzNSIsImh0dHA6Ly9sb2NhbGhvc3Q6NTIyOSIsImh0dHBzOi8vbG9jYWxob3N0OjcxODAiXSwibmJmIjoxNjk0MzIyNTc5LCJleHAiOjE3MDIxODQ5NzksImlhdCI6MTY5NDMyMjU4MCwiaXNzIjoiZG90bmV0LXVzZXItand0cyJ9.vk88fd6F9qtWO0xrIhe38TCNbYQtCDp1WhSsaHXJShk

Теперь мы будем использовать Curl для вызова вашего веб-API с включенной аутентификацией. Скопируйте строку после «Token:» из предыдущего шага и используйте ее в следующей команде командной строки, заменив {token}:

curl -i -H "Authorization: Bearer {token}" https://localhost:7180/secret

Если вы используете пример проекта, это вернет следующее:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sat, 09 Sep 2023 03:47:31 GMT
Server: Kestrel
Transfer-Encoding: chunked

This is a secret!!

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

Шаг 3. Добавьте к действию авторизацию на основе ролей

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

Начнем с добавления авторизации на основе ролей к действию в нашем веб-API. Добавьте следующую строку в действие вашего контроллера:

[Authorize(Roles = "Administrator")]

Теперь к этому действию могут получить доступ только JWT с ролью администратора. Давайте создадим JWT с этой ролью с помощью следующей команды в командной строке:

dotnet user-jwts create --role Administrator

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

curl -i -H "Authorization: Bearer {token}" https://localhost:7180/secret/admin

Шаг 4. Добавьте к действию авторизацию на основе утверждений

Добавьте следующую строку в раздел запуска вашего приложения:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
});

Этот код добавляет политику, требованием которой является наличие утверждения под названием «EmployeeNumber». Теперь давайте защитим действие с помощью этой политики, добавив следующий код в действие в вашем контроллере:

[Authorize(Policy = "EmployeeOnly")]

Мы можем создать JWT, который будет соответствовать этой Политике, с помощью следующей команды:

dotnet user-jwts create --claim "EmployeeNumber=123456"

И мы можем протестировать с помощью следующей команды:

curl -i -H "Authorization: Bearer {token}" https://localhost:7180/secret/employee

Сводка

И вот оно — аутентификация и авторизация JWT в нашем приложении .NET Core 7! Это руководство намеренно сделано простым и не рассматривает различные проверки JWT, но особенно важно отметить, что в вашем собственном коде вы захотите добавить TokenValidationParameters в AddJwtBearer. вызов для проверки того, что отправленному JWT можно доверять. Обычно это делается путем проверки эмитента и SigningKey.

Пожалуйста 👏 эту статью, если она вам понравилась и вы хотите увидеть больше!

Следуйте за мной в X (Twitter)