用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/rudironsoni/Synaxis --skill dotnet-api-security命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Routes .NET/C# work to domain skills. Loads coding-standards for code paths.
基于 SOC 职业分类
正在显示 SKILL.md
| name | dotnet-api-security |
| category | web |
| subcategory | security |
| description | Secures ASP.NET Core APIs. Identity, OAuth/OIDC, JWT bearer, passkeys, CORS, rate limiting. |
| license | MIT |
| targets | ["*"] |
| tags | ["api","dotnet","skill"] |
| version | 0.0.1 |
| author | dotnet-agent-harness |
| invocable | true |
| claudecode | {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} |
| codexcli | {"short-description":".NET skill guidance for api tasks"} |
| opencode | {"allowed-tools":["Read","Grep","Glob","Bash","Write","Edit"]} |
| copilot | {} |
| geminicli | {} |
| antigravity | {} |
API-level authentication, authorization, and security patterns for ASP.NET Core. This skill owns API auth implementation: ASP.NET Core Identity configuration, OAuth 2.0/OIDC integration, JWT bearer token handling, passkey (WebAuthn) authentication, CORS policies, Content Security Policy headers, and rate limiting.
Cross-references: [skill:dotnet-security-owasp] for OWASP security principles, [skill:dotnet-secrets-management] for secrets handling, [skill:dotnet-cryptography] for cryptographic best practices.
ASP.NET Core Identity provides user management, password hashing, role-based authorization, and two-factor authentication out of the box. It is the recommended starting point for applications that manage their own user accounts.
builder.Services.AddIdentityApiEndpoints<ApplicationUser>(options =>
{
// Password requirements
options.Password.RequiredLength = 12;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Password.RequireDigit = true;
// Lockout
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
var app = builder.Build();
app.MapIdentityApi<ApplicationUser>();
```text
`MapIdentityApi<TUser>()` provides pre-built token-based authentication endpoints SPAs mobile clients without
Razor UI:
| Endpoint | Method | Description |
| --------------- | -------- | ----------------------------------- |
| `/register` | POST | Create a user account |
| `/login` | POST | Authenticate receive tokens |
| `/refresh` | POST | Refresh an expired access token |
| `/confirmEmail` | GET | Confirm email address |
| `/manage/info` | GET/POST | Get/update user profile |
| `/manage/a` | POST | Configure two-factor authentication |
---
;
options.Scope.Add();
options.Scope.Add();
options.MapInboundClaims = ;
options.TokenValidationParameters.NameClaimType = ;
options.TokenValidationParameters.RoleClaimType = ;
});
```text
**Gotcha:** `MapInboundClaims = ` ;
});
builder.Services.AddAuthorization();
app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet(, (ClaimsPrincipal user) =>
TypedResults.Ok( { Name = user.Identity?.Name }))
.RequireAuthorization();
```text
```csharp
builder.Services.AddAuthorizationBuilder()
.AddPolicy(, policy =>
policy.RequireRole())
.AddPolicy(, policy =>
policy.RequireClaim(, ))
.SetFallbackPolicy( AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build());
```text
---
.NET introduces built-;
app = builder.Build();
app.MapIdentityApi<ApplicationUser>();
```text
Client calls `/passkey/register/options` to a `PublicKeyCredentialCreationOptions` challenge
;
});
options.AddPolicy(, policy =>
{
policy.WithOrigins()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
app = builder.Build();
app.UseCors(app.Environment.IsDevelopment() ? : );
```text
- **`AllowAnyOrigin()` + `AllowCredentials()`** rejected at runtime ASP.NET Core. But
`SetIsOriginAllowed(_ => )` + `AllowCredentials()` silently allows all origins -- never use pattern.
- **Preflight caching:** Without `SetPreflightMaxAge`, browsers send an OPTIONS request before every cross-origin
request. =>
{
context.Response.Headers.Append(
,
);
context.Response.Headers.Append(, );
context.Response.Headers.Append(, );
context.Response.Headers.Append(, );
context.Response.Headers.Append(,
);
next();
});
``` =>
{
nonce = Convert.ToBase64String(RandomNumberGenerator.GetBytes());
context.Items[] = nonce;
context.Response.Headers.Append(
,
);
next();
});
```text
---
ASP.NET Core includes built-;
limiterOptions.QueueLimit = ;
});
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});
app = builder.Build();
app.UseRateLimiter();
app.MapGet(, GetProducts)
.RequireRateLimiting();
```text
```csharp
builder.Services.AddRateLimiter(options =>
{
options.AddSlidingWindowLimiter(, limiterOptions =>
{
limiterOptions.PermitLimit = ;
limiterOptions.Window = TimeSpan.FromMinutes();
limiterOptions.SegmentsPerWindow = ;
limiterOptions.QueueLimit = ;
});
});
```text
```csharp
builder.Services.AddRateLimiter(options =>
{
options.AddTokenBucketLimiter(, limiterOptions =>
{
limiterOptions.TokenLimit = ;
limiterOptions.ReplenishmentPeriod = TimeSpan.FromSeconds();
limiterOptions.TokensPerPeriod = ;
limiterOptions.QueueLimit = ;
});
});
```text
```csharp
builder.Services.AddRateLimiter(options =>
{
options.AddConcurrencyLimiter(, limiterOptions =>
{
limiterOptions.PermitLimit = ;
limiterOptions.QueueLimit = ;
limiterOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});
});
```text
```csharp
builder.Services.AddRateLimiter(options =>
{
options.AddPolicy(, httpContext =>
{
userId = httpContext.User.FindFirstValue(ClaimTypes.NameIdentifier)
?? httpContext.Connection.RemoteIpAddress?.ToString()
?? ;
RateLimitPartition.GetFixedWindowLimiter(userId,
_ => FixedWindowRateLimiterOptions
{
PermitLimit = ,
Window = TimeSpan.FromMinutes()
});
});
});
```text
**Gotcha:** `UseRateLimiter()` must be called after `UseRouting()` before `UseAuthorization()` endpoint mapping
to apply correctly.
---
**Do use `AllowAnyOrigin()` production CORS policies** -- always specify origins. See
[] CORS security implications.
**Do forget `MapInboundClaims = `** external OIDC providers -- without it, claim types are
remapped to XML , .
3. ** ``** --
. [:--].
4. ** `` ``** --
401 . 1-2 .
5. ** ** -- `()` `()`, `()`
`()`.
6. ** `()` `()` ** --
.
7. ** ** -- `/` `/` - .
.
8. ** - ** -- (``,
) - .
---
##
- . 8.0+ ( , , , )
- . 10.0 /
- ``
- ``
- `` ( . 7+)
---
## ( )
** :** :
1. ** **: ``
2. ** **: ``
3. ** **: ``
4. ** **: ``
** :**
- ✅ ** **: , , ,
- ✅ ** /**: , ,
- ✅ ****: ,
** :**
```
# :
: //
: " "
# :
: "/"
: "//"
```
##
- [ ](:
- [ ](:
- [ ](:
- [ 2.0 / ](:
- [ ](:
- [ ](:
- [/](: