К основному содержанию
скилл CX Codex

authentication · codewithmukesh — скилл для Claude Code: JWT, OIDC и политики

Скилл для ИИ-агента, который подсказывает, как правильно настроить аутентификацию и авторизацию в ASP.NET Core: JWT, OIDC, Identity, политики.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add codewithmukesh/dotnet-claude-kit --skill authentication -a claude-code
Открыть на GitHub

Что делает authentication

Скилл кладёт в контекст агента готовые шаблоны для ASP.NET Core: настройку JWT bearer, генерацию токенов, политики авторизации, OpenID Connect и доступ к текущему пользователю. Агент подхватывает его сам, когда в разговоре мелькают «auth», «JWT», «bearer token», «OIDC», «claims», «roles» или «RequireAuthorization».

Внутри — четыре принципа и набор паттернов с кодом. Для управления пользователями скилл советует ASP.NET Identity вместо самодельного хранилища: там уже есть хеширование паролей, блокировка, двухфакторная аутентификация и подтверждение почты. Для API — bearer-токены, для Blazor и MVC — cookie. Генерацию токенов скилл строит на JsonWebTokenHandler из Microsoft.IdentityModel.JsonWebTokens, а JwtSecurityTokenHandler называет устаревшим стеком.

Отдельный раздел — антипаттерны. Роли строками вида [Authorize(Roles = "Admin,SuperAdmin,Manager")] скилл считает плохой практикой: их трудно рефакторить и тестировать, поэтому предлагает политики. Секреты в appsettings.json тоже попадают в список плохого — для разработки есть dotnet user-secrets, для продакшена переменные окружения. И не отключайте проверки токена: ValidateLifetime = false в примерах помечено как «DEFINITELY DON'T». Если у вас уже есть рабочая схема аутентификации, этот скилл будет спорить с ней — он тянет проект к политикам и Identity.

Какие задачи решает

  • настроить JWT bearer в ASP.NET Core без ошибок в параметрах валидации
  • защитить группу эндпоинтов одной политикой вместо ролей строками
  • сгенерировать токен с ролями и клаймами через актуальный обработчик
  • подключить внешний провайдер идентификации по OpenID Connect
  • вынести секреты JWT из appsettings.json в user secrets

Примеры запросов агенту

  • Помоги настроить JWT bearer аутентификацию в Program.cs
  • Сделай политику CanManageOrders с проверкой клайма permission
  • Переведи [Authorize(Roles = "Admin")] на политики авторизации

Как установить authentication

1Через Skills CLI (Vercel)

npx skills add codewithmukesh/dotnet-claude-kit --skill authentication -a claude-code

2Вручную: положить файлы

~/.claude/skills/authentication/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/authentication/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о authentication

Как установить authentication в Claude?

Выполните npx skills add codewithmukesh/dotnet-claude-kit --skill authentication -a claude-code. Скилл появится в ~/.claude/skills/authentication/SKILL.md.

Что делает скилл authentication?

Даёт агенту шаблоны аутентификации и авторизации для ASP.NET Core: JWT bearer, OpenID Connect, ASP.NET Identity, политики, роли и клаймы, API-ключи.

Когда агент загружает этот скилл?

Сам, когда в задаче речь о login, защите эндпоинтов, правилах авторизации или упомянуты «auth», «JWT», «OIDC», «claims», «roles», «RequireAuthorization».

Исходный текст

SKILL.md · MIT
---
name: authentication
description: >
  Authentication and authorization for ASP.NET Core. Covers JWT bearer tokens,
  OpenID Connect, ASP.NET Identity, authorization policies, role and claim-based
  authorization, and API key authentication.
  Load this skill when implementing login, protecting endpoints, designing
  authorization rules, or when the user mentions "auth", "JWT", "bearer token",
  "OIDC", "OpenID Connect", "Identity", "claims", "roles", "authorize",
  "RequireAuthorization", "API key", or "cookie auth".
---

# Authentication & Authorization

## Core Principles

1. **Use ASP.NET Identity for user management** — Don't build your own user store. Identity handles password hashing, lockout, two-factor, email confirmation, and (since .NET 10) built-in passkey/WebAuthn support for passwordless login.
2. **JWT for APIs, cookies for web apps** — APIs use Bearer token authentication; Blazor/MVC apps use cookie authentication.
3. **Policy-based authorization over roles** — Policies are testable, composable, and more expressive than `[Authorize(Roles = "Admin")]`.
4. **Never store secrets in code** — Use user secrets in development, Azure Key Vault / environment variables in production.

## Patterns

### JWT Bearer Authentication

```csharp
// Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!)),
            ClockSkew = TimeSpan.Zero
        };
    });

builder.Services.AddAuthorization();
```

### Token Generation

Use `JsonWebTokenHandler` from `Microsoft.IdentityModel.JsonWebTokens` — it is the maintained, span-based handler that ASP.NET Core itself validates with. `JwtSecurityTokenHandler` (System.IdentityModel.Tokens.Jwt) is the legacy stack.

```csharp
public sealed class TokenService(IConfiguration config, TimeProvider clock)
{
    private static readonly JsonWebTokenHandler TokenHandler = new();

    public string GenerateToken(User user, IEnumerable<string> roles)
    {
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Jwt:Key"]!));
        var now = clock.GetUtcNow();

        var descriptor = new SecurityTokenDescriptor
        {
            Issuer = config["Jwt:Issuer"],
            Audience = config["Jwt:Audience"],
            IssuedAt = now.UtcDateTime,
            Expires = now.AddHours(1).UtcDateTime,
            Claims = new Dictionary<string, object>
            {
                [JwtRegisteredClaimNames.Sub] = user.Id,
                [JwtRegisteredClaimNames.Email] = user.Email!,
                [JwtRegisteredClaimNames.Name] = user.UserName!,
                ["roles"] = roles.ToArray()
            },
            SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
        };

        return TokenHandler.CreateToken(descriptor);
    }
}
```

### Policy-Based Authorization

```csharp
// Define policies
builder.Services.AddAuthorizationBuilder()
    .AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"))
    .AddPolicy("CanManageOrders", policy => policy
        .RequireAuthenticatedUser()
        .RequireClaim("permission", "orders:write"))
    .AddPolicy("MinimumAge", policy => policy
        .AddRequirements(new MinimumAgeRequirement(18)));

// Custom requirement + handler
public class MinimumAgeRequirement(int minimumAge) : IAuthorizationRequirement
{
    public int MinimumAge => minimumAge;
}

public class MinimumAgeHandler(TimeProvider clock) : AuthorizationHandler<MinimumAgeRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        MinimumAgeRequirement requirement)
    {
        var dateOfBirthClaim = context.User.FindFirst("date_of_birth");
        if (dateOfBirthClaim is not null &&
            DateOnly.TryParse(dateOfBirthClaim.Value, out var dob) &&
            dob.AddYears(requirement.MinimumAge) <= DateOnly.FromDateTime(clock.GetUtcNow().DateTime))
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}
```

### Protecting Endpoints

```csharp
// Protect an entire group
app.MapGroup("/api/admin")
    .WithTags("Admin")
    .RequireAuthorization("AdminOnly")
    .MapAdminEndpoints();

// Protect individual endpoints
group.MapPost("/", CreateOrder)
    .RequireAuthorization("CanManageOrders");

// Allow anonymous on a protected group
group.MapGet("/public-info", GetPublicInfo)
    .AllowAnonymous();
```

### OpenID Connect (External Identity Provider)

```csharp
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = builder.Configuration["Oidc:Authority"];
    options.ClientId = builder.Configuration["Oidc:ClientId"];
    options.ClientSecret = builder.Configuration["Oidc:ClientSecret"];
    options.ResponseType = "code";
    options.SaveTokens = true;
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
});
```

### Accessing Current User

```csharp
// In minimal API handlers — inject ClaimsPrincipal or HttpContext
group.MapGet("/me", (ClaimsPrincipal user) =>
{
    var userId = user.FindFirstValue(ClaimTypes.NameIdentifier);
    var email = user.FindFirstValue(ClaimTypes.Email);
    return TypedResults.Ok(new { userId, email });
}).RequireAuthorization();
```

## Anti-patterns

### Don't Use Role Strings Everywhere

```csharp
// BAD — magic strings, hard to refactor, not testable
[Authorize(Roles = "Admin,SuperAdmin,Manager")]
public class AdminController { }

// GOOD — policy-based
builder.Services.AddAuthorizationBuilder()
    .AddPolicy("AdminAccess", p => p.RequireRole("Admin", "SuperAdmin", "Manager"));

group.MapGet("/", Handler).RequireAuthorization("AdminAccess");
```

### Don't Store Secrets in appsettings.json

```json
// BAD — committed to source control
{
  "Jwt": {
    "Key": "super-secret-key-12345"
  }
}
```

```bash
# GOOD — use user secrets in development
dotnet user-secrets set "Jwt:Key" "super-secret-key-12345"
```

### Don't Skip Token Validation

```csharp
// BAD — disabling validation
options.TokenValidationParameters = new TokenValidationParameters
{
    ValidateIssuer = false,      // DON'T
    ValidateAudience = false,    // DON'T
    ValidateLifetime = false,    // DEFINITELY DON'T
};

// GOOD — validate everything (see JWT Bearer Authentication pattern above for full setup)
```

## Decision Guide

| Scenario | Recommendation |
|----------|---------------|
| REST API | JWT Bearer authentication |
| Blazor Server / MVC | Cookie authentication |
| External identity provider | OpenID Connect |
| User registration / login | ASP.NET Identity |
| Passwordless login | ASP.NET Identity passkeys (WebAuthn, built-in since .NET 10) |
| Permission checking | Policy-based authorization |
| Multi-tenant API | Claims-based with tenant claim |
| API-to-API communication | Client credentials (OAuth 2.0) |
| Simple API keys | Custom `AuthenticationHandler<T>` |

© codewithmukesh · MIT · codewithmukesh/dotnet-claude-kit

Похожие скиллы

Всё по теме «Бэкенд и API» →

Сначала — authentication от других авторов.

authentication dpearson2699 Помогает собирать сценарии входа в iOS через Apple ID, passkeys, OAuth и биометрию. Пригодится, когда нужно связать авторизацию с проверкой учётных данных и серверной валидацией. CX Codex +1 3 900установок catalyst-authentication catalystbyzoho Помогает настроить вход, регистрацию и OAuth-подключения в Zoho Catalyst. Предупреждает о несовпадении ZAID между средами и ошибках локального запуска. CX Codex +1 999установок auth0-authentication Mindrally Скилл задаёт агенту правила работы с Auth0: потоки авторизации, Actions, проверка токенов и защита редиректов. CX Codex +1 700установок api-authentication aj-geddes Скилл по аутентификации API: JWT, OAuth 2.0, API-ключи и работа с сессиями. Пригодится, когда закрываешь эндпоинты или делаешь вход в приложение. CX Codex +1 607установок testing-api-authentication-weaknesses mahipal Скилл проверяет аутентификацию API на уязвимости обхода, ошибки в JWT и открытые эндпоинты. Помогает протестировать REST API перед релизом. CX Codex +1 484установок authentication-setup akillness Помогает выбрать способ аутентификации для веб-приложения или API и разложить её по границам: что берёт провайдер, что остаётся в приложении. CX Codex +1 368установок microsoft-azure-webjobs-extensions-authentication-events-dotnet Microsoft Скилл для работы с кастомными событиями аутентификации Microsoft Entra ID в .NET: добавление claims в токены, сбор атрибутов, OTP. 1установок

Из того же набора46

de-sloppify Наводит порядок в .NET-коде по семи шагам: от форматирования до передачи CancellationToken. Нужен перед релизом, после крупных изменений или обновления зависимостей. CX Codex +1 2 800установок logging Скилл про наблюдаемость в .NET 10: разводит liveness и readiness, прокидывает correlation ID и задаёт уровни логов. CX Codex +1 2 800установок ci-cd Скилл помогает создавать YAML-пайплайны для проектов на .NET. Пригодится для быстрой настройки GitHub Actions и Azure DevOps с этапами сборки, тестов и публикации. CX Codex +1 2 800установок resilience Скилл для ИИ-агента, который подсказывает, как строить отказоустойчивые вызовы в .NET 10 на Polly v8: retry, circuit breaker, таймауты, fallback. CX Codex +1 2 800установок dependency-injection Скилл внедряет паттерны dependency injection для .NET 10: выбор времён жизни сервисов, keyed services, декораторы через Scrutor и защиту от captive dependency. CX Codex +1 2 800установок minimal-api Скилл для ИИ-агентов, который ведёт по минимальным API .NET 10: группы эндпоинтов, TypedResults, фильтры и OpenAPI. CX Codex +1 2 800установок testing Скилл задаёт стратегию тестирования приложений .NET 10: интеграционные тесты через WebApplicationFactory, реальные базы в Testcontainers, снапшоты Verify. CX Codex +1 2 800установок ef-core Набор паттернов Entity Framework Core для .NET 10. Помогает настроить DbContext, пакетные обновления, миграции и проекции запросов без лишней нагрузки на базу данных. CX Codex +1 2 800установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой