csharp-authlisted
Install: claude install-skill CloudyWing/ai-dotfiles
# ASP.NET Core 認證授權規範
機密管理(signing key、client secret 不落原始碼)依全域 §2 Security Baseline,本文件不重複。
## JWT Bearer 驗證(Crucial)
- 有 OIDC Provider(IdP)時,一律設定 `Authority` 走 discovery 文件自動取得 JWKS,**禁止**在程式碼或設定檔中硬編碼簽章金鑰或手動貼上 JWKS 內容。
- `TokenValidationParameters` 必須明確設定,不依賴預設值:
```csharp
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.Authority = builder.Configuration["Auth:Authority"];
options.TokenValidationParameters = new TokenValidationParameters {
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = builder.Configuration["Auth:Audience"],
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes(1)
};
options.MapInboundClaims = false;
});
```
- **ClockSkew**:明確設為 1 分鐘以內,不使用預設的 5 分鐘(過長的容忍值等於延長 Token 有效期)。
- **僅開發環境**允許 `RequireHttpsMetadata = false`,且必須以環境判斷包住,不得寫死。
## Claims 慣例(Crucial)
- 設定 `MapInboundClaims = false`,保留 OIDC 標準 claim 名稱(`sub`、`email`、`name`),**禁止**依賴 Microsoft 舊式 SOAP claim URI(`http://schemas.xmlsoap.org/...`)的自動改名。
- 使用者識別一律取 `sub`,不使用 `NameIdentifier` 與 `sub` 混用;專案內以擴充方法統一���值:
```csharp
public static class ClaimsPrincipalExtensions {
public static string GetUserId(this ClaimsPrincipal principal) {
return principal.FindFirstValue("sub")
?? throw new InvalidOperationException("Token 缺少 sub claim。");
}
}
```
- 自訂 claim 使用小寫 snake_case 或短名稱(如 `tenant_id`、