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

在会话结束时把已完成工作、待办任务与经验写入交接文件,并在会话开始时重新载入。

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个月前更新