Authentication

codewithmukesh/dotnet-claude-kit/skills/authentication

作者 codewithmukesh23300897f4d1無授權條款754 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫2 個月前更新

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".

AI 產生的概覽

指導 ASP.NET Core 的驗證與授權,涵蓋 JWT 持有人權杖、OpenID Connect、Identity 與原則。

功能
此技能提供在 ASP.NET Core 中實作驗證與授權的參考指引與程式碼模式。內容涵蓋 JWT 持有人權杖的設定與驗證、權杖產生、含自訂需求的原則式授權、端點保護、OpenID Connect,以及存取目前使用者。它也列出反模式,並提供將情境對應到建議做法的決策指南。
適用情境
在 ASP.NET Core 中實作登入、保護端點或設計授權規則時使用。涉及 JWT、持有人權杖、OIDC、ASP.NET Identity、宣告、角色、API 金鑰或 Cookie 驗證時也適用。
執行需求
不包含指令碼,僅為說明性內容。依其中的模式操作需要 ASP.NET Core 專案及相關 NuGet 套件(例如 Microsoft.IdentityModel.JsonWebTokens),以及 JWT 簽發者、對象與金鑰的設定值。

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.csbuilder.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 policiesbuilder.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 + handlerpublic 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 groupapp.MapGroup("/api/admin")    .WithTags("Admin")    .RequireAuthorization("AdminOnly")    .MapAdminEndpoints();
// Protect individual endpointsgroup.MapPost("/", CreateOrder)    .RequireAuthorization("CanManageOrders");
// Allow anonymous on a protected groupgroup.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 HttpContextgroup.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-basedbuilder.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 developmentdotnet user-secrets set "Jwt:Key" "super-secret-key-12345"

Don't Skip Token Validation

csharp
// BAD — disabling validationoptions.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

ScenarioRecommendation
REST APIJWT Bearer authentication
Blazor Server / MVCCookie authentication
External identity providerOpenID Connect
User registration / loginASP.NET Identity
Passwordless loginASP.NET Identity passkeys (WebAuthn, built-in since .NET 10)
Permission checkingPolicy-based authorization
Multi-tenant APIClaims-based with tenant claim
API-to-API communicationClient credentials (OAuth 2.0)
Simple API keysCustom AuthenticationHandler<T>

來源與署名

來源:codewithmukesh/dotnet-claude-kit位於skills/authentication提交2330089

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架

更多來自 codewithmukesh/dotnet-claude-kit 的技能

Wrap Up

codewithmukesh

在 session 結束時把已完成工作、待辦事項與經驗寫入交接檔案,並在 session 開始時重新載入。

Productivity & Workflow7542 個月前更新

Workflow Mastery

codewithmukesh

Claude Code workflow mastery for .NET developers. Covers parallel execution with git worktrees, plan mode strategy, verification loops, auto-formatting hooks, permission setup for dotnet CLI, prompting techniques, subagent patterns, and context discipline — token budget management, MCP-first navigation, lazy loading, and subagent isolation — all adapted for the .NET ecosystem. Load this skill when setting up Claude Code for a .NET project, optimizing workflows, running parallel sessions, when context is running low or sessions feel sluggish, when exploring a large codebase efficiently, or when the user mentions "productivity", "workflow", "parallel", "worktree", "plan mode", "permissions", "hooks", "10x", "setup Claude Code", "speed up development", "context", "tokens", "budget", "running out of context", "too many files", or "large codebase". Inspired by tips from Boris Cherny (creator of Claude Code) and the Anthropic team.

待分類7542 個月前更新

Vertical Slice

codewithmukesh

指導 .NET 開發者以垂直切片架構組織應用程式,涵蓋功能資料夾、端點分組與處理常式模式。

Software Development7542 個月前更新

Testing

codewithmukesh

Testing strategy for .NET 10 applications. Covers xUnit v3, WebApplicationFactory for integration tests, Testcontainers for real database testing, Verify for snapshot testing, and the AAA pattern. Load this skill when writing tests, setting up test infrastructure, reviewing test coverage, or when the user mentions "test", "xUnit", "WebApplicationFactory", "Testcontainers", "integration test", "unit test", "bUnit", "snapshot test", "Verify", "test coverage", "AAA pattern", "WireMock", or "FakeTimeProvider".

待分類7542 個月前更新

Tdd

codewithmukesh

Guided test-driven development workflow for .NET 10 using xUnit v3, WebApplicationFactory, Testcontainers, and Verify snapshots. Follows the strict red-green-refactor cycle. Use when: "TDD", "test-driven", "let's TDD this", "red green refactor", "write the test first", or when building a feature with clear acceptance criteria.

待分類7542 個月前更新

Spec

codewithmukesh

透過結構化提問,把模糊的功能想法轉化為雙方確認並持久化的規格文件。

Productivity & Workflow7542 個月前更新