TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3204 1.66K
День 2676. #ЗаметкиНаПолях
Реализуем Немедленный Отзыв Токенов в .NET 10. Окончание

Начало

Настройка токенов
Переключение клиента на использование референтных токенов - одна строка конфигурации. При определении клиента в IdentityServer установите AccessTokenType:
new Client
{
ClientId = "banking_app",
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,

// Вот эта строка
AccessTokenType = AccessTokenType.Reference,

AllowOfflineAccess = true,
RedirectUris = { "https://banking.example.com/signin-oidc" },
AllowedScopes = { "openid", "profile", "accounts.read", "transfers.write" }
};

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

Настройка API для интроспекции
Ваш API должен знать, как проверять эти непрозрачные токены. Вместо (или в дополнение к) проверке JWT настроим интроспекцию OAuth 2.0. Сначала определите ресурс API с секретом, который API будет использовать для аутентификации с конечной точкой интроспекции:
new ApiResource("banking_api")
{
Scopes = { "accounts.read", "transfers.write" },
ApiSecrets = { new Secret("api_secret".Sha256()) }
};

Затем в Program.cs вашего API зарегистрируйте обработчик интроспекции. Обратите внимание, что обработчик должен использовать ту же схему аутентификации, что и та, которую вы хотите использовать для интроспекции:
builder.Services.AddAuthentication("token")
.AddOAuth2Introspection("token", opts =>
{
opts.Authority = "https://identity.banking.example.com";
opts.ClientId = "banking_api";
opts.ClientSecret = "api_secret";
});

Если вам необходимо поддерживать как JWT, так и референтные токены (например, во время миграции), вы можете зарегистрировать обработчики обоих типов и использовать переадресацию для направления токенов к нужному обработчику:
builder.Services.AddAuthentication("token")
.AddJwtBearer("token", opts =>
{
opts.Authority = "https://identity.banking.example.com";
opts.Audience = "banking_api";
opts.TokenValidationParameters.ValidTypes = ["at+jwt"];
opts.ForwardDefaultSelector = Selector.ForwardReferenceToken("introspection");
})
.AddOAuth2Introspection("introspection", opts =>
{
opts.Authority = "https://identity.banking.example.com";
opts.ClientId = "banking_api";
opts.ClientSecret = "api_secret";
});


Отзыв токена
Теперь ваша система поддержки (или автоматизированный конвейер обнаружения угроз) сможет немедленно отозвать токен, используя конечную точку отзыва IdentityServer, которая реализует RFC 7009:
using Duende.IdentityModel.Client;

var client = new HttpClient();

var result = await client.RevokeTokenAsync(
new TokenRevocationRequest
{
Address = "https://identity.banking.example.com/connect/revocation",
ClientId = "banking_app",
ClientSecret = "secret",
Token = stolenAccessToken
});

if (result.IsError)
logger.LogError("Token revocation failed: {Error}", result.Error);

После отзыва токен удаляется из хранилища предоставленных прав IdentityServer. Следующий запрос на проверку подлинности от любого API подтвердит, что токен больше не активен.

Не забывайте: вы также можете (и должны) отозвать токен обновления пользователя, чтобы предотвратить незаметное получение клиентом нового токена доступа:
await client.RevokeTokenAsync(
new TokenRevocationRequest
{
Address = "https://identity.banking.example.com/connect/revocation",
ClientId = "banking_app",
ClientSecret = "secret",
Token = refreshToken
});

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

Источник: https://duendesoftware.com/blog/20260428-the-emergency-stop-button-implementing-immediate-token-revocation-in-dotnet-10
  • 👍 1
More from @netdeveloperdiary
  1. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  2. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  3. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  4. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  5. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →