OAuth клиент для C# (.NET): библиотека IdentityModel и интеграция с OAuth 2.0

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

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

Начать курс

Библиотека IdentityModel для OAuth 2.0 и OpenID Connect в C# (.NET)

При разработке современных веб-приложений, мобильных клиентов или серверных API на платформе .NET практически всегда возникает необходимость интеграции с внешними провайдерами аутентификации (Google, GitHub, Microsoft и др.) или собственным сервером авторизации. IdentityModel — это легковесная, но мощная библиотека для C#, которая предоставляет удобный OAuth клиент для работы с протоколами OAuth 2.0 и OpenID Connect. Она является де-факто стандартом в экосистеме .NET для реализации потоков авторизации.

В этой статье мы подробно разберем, как использовать IdentityModel для создания OAuth клиента, получения токенов доступа и их обновления. Примеры кода будут на C# (.NET 6+).

Установка и подключение

Для начала работы установите пакет через NuGet Package Manager:

dotnet add package IdentityModel

Или через консоль менеджера пакетов:

Install-Package IdentityModel

После установки вы получаете доступ к классам HttpClient extensions, DiscoveryClient, TokenClient и другим вспомогательным утилитам.

Базовый сценарий: получение токена через Client Credentials

Этот поток используется для сервер-серверной аутентификации, когда клиент (ваше приложение) запрашивает токен от имени самого себя, а не пользователя.

Пример настройки OAuth клиента:

using IdentityModel.Client;
using System.Net.Http;
using System.Threading.Tasks;

public async Task<string> GetAccessTokenAsync()
{
    var client = new HttpClient();

    // 1. Получаем документ обнаружения (discovery) от сервера авторизации
    var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com");
    if (disco.IsError)
    {
        throw new Exception($"Ошибка получения discovery: {disco.Error}");
    }

    // 2. Запрашиваем токен, используя client_id и client_secret
    var tokenResponse = await client.RequestClientCredentialsTokenAsync(
        new ClientCredentialsTokenRequest
        {
            Address = disco.TokenEndpoint,
            ClientId = "your-client-id",
            ClientSecret = "your-client-secret",
            Scope = "api1 api2" // запрашиваемые разрешения
        });

    if (tokenResponse.IsError)
    {
        throw new Exception($"Ошибка получения токена: {tokenResponse.Error}");
    }

    return tokenResponse.AccessToken;
}

В этом примере мы используем методы расширения из пространства имен IdentityModel.Client. Библиотека автоматически обрабатывает сериализацию JSON, заголовки и парсинг ответов.

Поток Authorization Code (с участием пользователя)

Для приложений с пользовательским интерфейсом (ASP.NET Core MVC, Blazor, десктоп) чаще используется код авторизации. IdentityModel интегрируется с Microsoft.AspNetCore.Authentication.OpenIdConnect, но также предоставляет низкоуровневые средства для ручной реализации.

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

public async Task<TokenResponse> ExchangeCodeForTokenAsync(string authorizationCode, string redirectUri)
{
    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com");

    var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(
        new AuthorizationCodeTokenRequest
        {
            Address = disco.TokenEndpoint,
            ClientId = "your-client-id",
            ClientSecret = "your-client-secret",
            Code = authorizationCode,
            RedirectUri = redirectUri
        });

    return tokenResponse;
}

Обновление токена (Refresh Token)

Access token'ы обычно живут недолго (например, 1 час). Для продления сессии используется refresh token. IdentityModel делает этот процесс тривиальным:

public async Task<TokenResponse> RefreshAccessTokenAsync(string refreshToken)
{
    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com");

    var tokenResponse = await client.RequestRefreshTokenAsync(
        new RefreshTokenRequest
        {
            Address = disco.TokenEndpoint,
            ClientId = "your-client-id",
            ClientSecret = "your-client-secret",
            RefreshToken = refreshToken
        });

    return tokenResponse;
}

Работа с JWT и проверка токенов

IdentityModel включает утилиты для работы с JWT (JSON Web Tokens). Вы можете декодировать payload без проверки подписи:

using IdentityModel.Jwt;

var token = "eyJhbGciOiJSUzI1NiIs...";
var payload = JwtToken.Decode(token);
Console.WriteLine(payload["sub"]); // идентификатор пользователя

Для полной верификации токена (проверка подписи, срока действия, аудитории) рекомендуется использовать Microsoft.IdentityModel.Tokens вместе с IdentityModel.

Интеграция с HttpClient и политиками повторов

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