界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
效率与协作 · SKILL.md

aspnet-identity

aspnet-identity

【效率与协作】ASP.NET Core Identity for authentication, roles, claims, and external providers. Covers Identity setup, customization, and token-based auth. USE WHEN: user mentions "ASP.NET Identity", "user authentication", ".NET auth", "roles and claims", "Identity scaffolding", "external login providers" DO NOT USE FOR: JWT-only auth without Identity, Spring Sec…

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: aspnet-identity description: | ASP.NET Core Identity for authentication, roles, claims, and external providers. Covers Identity setup, customization, and token-based auth.

USE WHEN: user mentions "ASP.NET Identity", "user authentication", ".NET auth", "roles and claims", "Identity scaffolding", "external login providers"

DO NOT USE FOR: JWT-only auth without Identity, Spring Security - use spring-security allowed-tools: Read, Grep, Glob, Write, Edit

ASP.NET Core Identity - Quick Reference

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: aspnet-core for Identity documentation.

Setup

// Program.cs
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
    options.Password.RequireDigit = true;
    options.Password.RequiredLength = 12;
    options.Password.RequireNonAlphanumeric = true;
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();

Custom User Entity

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; } = default!;
    public string LastName { get; set; } = default!;
    public DateTime CreatedAt { get; set; }
}

Registration & Login

public class AuthService
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;

    public async Task<IdentityResult> RegisterAsync(RegisterRequest request)
    {
        var user = new ApplicationUser
        {
            UserName = request.Email,
            Email = request.Email,
            FirstName = request.FirstName,
            LastName = request.LastName,
        };
        return await _userManager.CreateAsync(user, request.Password);
    }

    public async Task<SignInResult> LoginAsync(LoginRequest request)
    {
        return await _signInManager.PasswordSignInAsync(
            request.Email, request.Password, request.RememberMe, lockoutOnFailure: true);
    }
}

Role-Based Authorization

// Seed roles
using var scope = app.Services.CreateScope();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
foreach (var role in new[] { "Admin", "User", "Manager" })
{
    if (!await roleManager.RoleExistsAsync(role))
        await roleManager.CreateAsync(new IdentityRole(role));
}

// Assign role
await _userManager.AddToRoleAsync(user, "Admin");

// Controller
[Authorize(Roles = "Admin")]
public IActionResult AdminPanel() => Ok();

// Policy-based
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdmin", policy => policy.RequireRole("Admin"));
    options.AddPolicy("MinAge", policy =>
        policy.RequireClaim("DateOfBirth")
              .RequireAssertion(ctx =>
              {
                  var dob = DateTime.Parse(ctx.User.FindFirst("DateOfBirth")!.Value);
                  return DateTime.Today.Year - dob.Year >= 18;
              }));
});

External Login Providers

builder.Services.AddAuthentication()
    .AddGoogle(options =>
    {
        options.ClientId = builder.Configuration["Auth:Google:ClientId"]!;
        options.ClientSecret = builder.Configuration["Auth:Google:ClientSecret"]!;
    })
    .AddMicrosoftAccount(options =>
    {
        options.ClientId = builder.Configuration["Auth:Microsoft:ClientId"]!;
        options.ClientSecret = builder.Configuration["Auth:Microsoft:ClientSecret"]!;
    });

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Custom password hashingInsecureUse Identity's PasswordHasher<T>
Storing plain-text passwordsSecurity riskIdentity hashes automatically
No account lockoutBrute-force vulnerableEnable lockout options
Roles in JWT claims onlyNot enforced server-sideValidate from store

Quick Troubleshooting

IssueLikely CauseSolution
Login always failsWrong password configCheck PasswordOptions
User not foundCase sensitivityIdentity is case-insensitive by default
Token expiredShort token lifetimeAdjust TokenLifespan
External login redirect failsWrong callback URLCheck provider's redirect URIs
我的收藏