OAuth 2.0 и JWT авторизация на C#: пошаговое руководство для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в OAuth 2.0 и JWT на C#

Современные веб-приложения требуют надежных механизмов безопасности. Два ключевых протокола — OAuth 2.0 и JWT (JSON Web Token) — стали стандартом де-факто для реализации авторизации и аутентификации. В этой статье мы разберем, как использовать эти технологии в экосистеме C# (.NET).

OAuth 2.0 — это протокол делегированного доступа, который позволяет приложениям получать ограниченный доступ к ресурсам пользователя без передачи его учетных данных. JWT, в свою очередь, представляет собой компактный и самодостаточный формат токенов, который часто используется для передачи информации об аутентификации между клиентом и сервером.

В этом руководстве мы создадим простое веб-API на ASP.NET Core, реализующее OAuth 2.0 с использованием JWT-токенов. Вы узнаете, как настроить генерацию, валидацию и защиту эндпоинтов.

Что такое OAuth 2.0 и JWT?

Прежде чем перейти к коду, давайте разберем основные концепции.

OAuth 2.0

OAuth 2.0 определяет четыре роли:

  • Resource Owner (владелец ресурса) — обычно пользователь.
  • Client (клиент) — приложение, которое хочет получить доступ.
  • Authorization Server (сервер авторизации) — выдает токены.
  • Resource Server (сервер ресурсов) — предоставляет защищенные данные.

Основной поток Authorization Code Grant включает: перенаправление пользователя на сервер авторизации, получение кода, обмен кода на токен доступа.

JWT (JSON Web Token)

JWT состоит из трех частей, разделенных точками:

  • Header — тип токена и алгоритм подписи (например, HS256).
  • Payload — данные (claims), такие как ID пользователя, роль, срок действия.
  • Signature — подпись, созданная с помощью секретного ключа.

Пример JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Настройка проекта ASP.NET Core

Создадим новый проект веб-API с поддержкой аутентификации.

dotnet new webapi -n OAuthJwtDemo
cd OAuthJwtDemo

Добавим необходимые NuGet-пакеты:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt

Конфигурация в appsettings.json

Добавьте секцию для JWT-настроек в файл appsettings.json:

{
  "JwtSettings": {
    "SecretKey": "YOUR_SUPER_SECRET_KEY_AT_LEAST_32_CHARS",
    "Issuer": "OAuthJwtDemo",
    "Audience": "OAuthJwtDemoClient",
    "ExpirationMinutes": 60
  }
}

Важно: В реальном проекте храните секретный ключ в User Secrets или Azure Key Vault.

Реализация сервиса генерации JWT

Создадим интерфейс и его реализацию для работы с токенами.

Интерфейс IJwtService

public interface IJwtService
{
    string GenerateToken(string userId, string role);
    ClaimsPrincipal ValidateToken(string token);
}

Реализация JwtService

public class JwtService : IJwtService
{
    private readonly JwtSettings _settings;

    public JwtService(IOptions<JwtSettings> settings)
    {
        _settings = settings.Value;
    }

    public string GenerateToken(string userId, string role)
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.NameIdentifier, userId),
            new Claim(ClaimTypes.Role, role),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };

        var key = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(_settings.SecretKey));
        var credentials = new SigningCredentials(key, 
            SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: _settings.Issuer,
            audience: _settings.Audience,
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(_settings.ExpirationMinutes),
            signingCredentials: credentials
        );

        return new JwtSecurityTokenHandler().WriteToken(token);
    }

    public ClaimsPrincipal ValidateToken(string token)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.UTF8.GetBytes(_settings.SecretKey);

        var principal = tokenHandler.ValidateToken(token, 
            new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = _settings.Issuer,
            ValidAudience = _settings.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(key)
        }, out _);

        return principal;
    }
}

Настройка аутентификации в Program.cs

В файле Program.cs настройте сервисы и middleware:

// Регистрация сервисов
builder.Services.Configure<JwtSettings>(
    builder.Configuration.GetSection("JwtSettings"));
builder.Services.AddScoped<IJwtService, JwtService>();

// Настройка аутентификации
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = 
        JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = 
        JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    var jwtSettings = builder.Configuration
        .GetSection("JwtSettings").Get<JwtSettings>();
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = jwtSettings.Issuer,
        ValidAudience = jwtSettings.Audience,
        IssuerSigningKey = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(jwtSettings.SecretKey))
    };
});

builder.Services.AddAuthorization();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();

Создание контроллера регистрации и логина

Блоги

Рекомендаций по книгам