
ASP.NET Core Cookie 认证实战指南从 Cookies 示例看登录、Claims 与登出全流程【免费下载链接】aspnetcoreASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.项目地址: https://gitcode.com/GitHub_Trending/as/aspnetcore本篇文章以 ASP.NET Core 官方仓库dotnet/aspnetcore中 src/Security/samples/Cookies 示例为蓝本完整讲解不依赖 Identity 框架、直接基于 Cookie 认证方案的登录、签发 Claims、访问控制与登出实现。读完本文你将掌握AddAuthenticationAddCookie的注册方式、HttpContext.SignInAsync手动签发身份的写法以及[Authorize]、LoginPath、AccessDeniedPath等关键配置在真实项目中的落地方法。示例演示流程官方 READMEsrc/Security/samples/Cookies/README.md给出了三段式的演示步骤这也是理解整个示例的入口运行应用点击导航栏的 MyClaims 选项卡由于MyClaims操作带有[Authorize]特性未登录的匿名用户会被重定向到登录页即LoginPath指定的/account/login。使用任意用户名和密码登录该示例不做真实的账号校验只要表单提交了用户名与密码即视为登录成功。重定向回/Home/MyClaims并展示用户 Claims登录成功后页面会列出当前用户的全部 Claims 以及认证票据AuthenticationProperties中的条目直观验证登录后身份信息如何被还原。README 同时明确指出示例中最值得阅读的两个类是 Startup.cs 和 Controllers/AccountController.cs。下面围绕它们逐层展开。项目结构一个最小可运行的 Cookie 认证 MVC 应用示例是一个标准的 MVC 项目Cookies.csprojMicrosoft.NET.Sdk.Web核心文件如下src/Security/samples/Cookies/ ├── Program.cs # 应用入口使用 Startup 类 ├── Startup.cs # 注册认证服务、配置请求管道 ├── ConfigureMyCookie.cs # 通过 IConfigureNamedOptions 自定义 Cookie 选项 ├── Controllers/ │ ├── AccountController.cs # 登录 / 登出 / AccessDenied │ └── HomeController.cs # Index 与受保护的 MyClaims └── Views/ ├── Account/Login.cshtml # 登录表单 ├── Account/AccessDenied.cshtml # 拒绝访问提示页 └── Home/MyClaims.cshtml # 展示 Claims 与 AuthenticationProperties应用入口 Program.cs 通过Host.CreateDefaultBuilder(args)与ConfigureWebHostDefaults启动并显式指定UseStartupStartup()因此全部认证逻辑集中在Startup中。注册认证服务默认 Scheme 与 Cookie 方案Startup.cs 的ConfigureServices是 Cookie 认证的起点public const string CookieScheme YourSchemeName; public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddAuthentication(CookieScheme) // 将默认 scheme 设置为 cookies .AddCookie(CookieScheme, options { options.AccessDeniedPath /account/denied; options.LoginPath /account/login; }); services.AddSingletonIConfigureOptionsCookieAuthenticationOptions, ConfigureMyCookie(); }这里有几个值得注意的细节默认 SchemeAddAuthentication(CookieScheme)中的字符串YourSchemeName被同时用作默认的认证方案名与 Cookie 方案名。方案名是后续[Authorize]、SignInAsync、SignOutAsync与ConfigureMyCookie区分不同认证方案的关键标识。LoginPath未认证用户访问受保护资源时重定向的地址示例中指向/account/login即AccountController.Login。AccessDeniedPath已登录但授权失败时跳转的地址示例中指向/account/denied对应AccessDenied视图Access is denied...。手动设置 Cookie 方案AddCookie返回的构建器还可以继续链式调用.AddCookie注册多个不同名称的 Cookie 方案或叠加其他方案如 JWT、Google、Facebook本例只注册了一个。从源码结构看AddAuthentication/AddCookie这些扩展方法分别位于 src/Security/Authentication/Core 与 src/Security/Authentication/Cookies/src 下最终都会把CookieAuthenticationHandler注册为对应方案名的认证处理器——这个处理器负责 Cookie 的读取、解密、票据还原与签发是整条认证链的底层执行者。深度自定义IConfigureOptions 注入式配置示例特意演示了既要复用其他服务、又要针对某个方案单独配置的进阶写法——ConfigureMyCookie.csinternal class ConfigureMyCookie : IConfigureNamedOptionsCookieAuthenticationOptions { public ConfigureMyCookie() { // 可以在此注入其他服务如数据库上下文、日志器等 } public void Configure(string name, CookieAuthenticationOptions options) { // 只配置你关心的 scheme if (name Startup.CookieScheme) { // options.LoginPath /someotherpath; } } public void Configure(CookieAuthenticationOptions options) Configure(Options.DefaultName, options); }其原理是AddCookie内部通过services.AddOptions()体系注册了默认的IConfigureNamedOptionsCookieAuthenticationOptions而这里再注册一个IConfigureOptionsCookieAuthenticationOptions单例Startup.cs选项系统在创建每个命名方案时都会调用它从而可以在 lambda 之外、以构造函数注入的方式组合任意服务并利用name参数区分不同方案。登录控制器手动创建 Claims 并签发身份README 重点点名的 AccountController.cs 展示了不借助 Identity、直接手工构造身份的登录流程。Login的 GET 版本用于渲染登录表单把returnUrl通过ViewData[ReturnUrl]传给视图POST 版本处理提交[HttpPost] public async TaskIActionResult Login(string userName, string password, string returnUrl null) { ViewData[ReturnUrl] returnUrl; // 通常 Identity 负责登录但这里可以直接手动处理 if (ValidateLogin(userName, password)) { var claims new ListClaim { new Claim(user, userName), new Claim(role, Member) }; await HttpContext.SignInAsync(new ClaimsPrincipal(new ClaimsIdentity(claims, Cookies, user, role))); if (Url.IsLocalUrl(returnUrl)) { return Redirect(returnUrl); } else { return Redirect(/); } } return View(); }关键点逐一拆解ValidateLogin永远返回true源码注释明确写着For this sample, all logins are successful即只验证表单确实提供了值不做真实账号比对。生产环境应替换为真实的用户校验逻辑。手动构造 Claimsnew Claim(user, userName)与new Claim(role, Member)是自定义 Claims其中user同时被指定为 Name Claim Type、role被指定为 Role Claim Type——这正是ClaimsIdentity构造器中后两个参数的作用它决定了User.Identity.Name与角色判断如[Authorize(Roles Member)]如何从 Claims 中取值。HttpContext.SignInAsync不传方案名时使用默认方案即前面注册的YourSchemeName。该方法由CookieAuthenticationHandler完成 Cookie 的加密、序列化与下发。开放重定向防护通过Url.IsLocalUrl(returnUrl)校验回跳地址只有本地 URL 才允许重定向否则回首页/这是防止开放重定向攻击的标准做法。登录表单Views/Account/Login.cshtml 是普通的 MVC 表单字段名为username/password并带有asp-route-returnurl标签助手回传ReturnUrl。受保护资源与授权HomeController.cs 演示了如何保护一个 Action[Authorize] public IActionResult MyClaims() { return View(); }匿名用户访问MyClaims时认证中间件发现没有有效票据会按CookieAuthenticationOptions.LoginPath将请求 302 到/account/login?ReturnUrl...登录成功后SignInAsync下发 Cookie随后的请求携带该 CookieCookieAuthenticationHandler验签解密后重建ClaimsPrincipal并挂载到HttpContext.User上[Authorize]校验通过最终渲染MyClaims视图。AccessDenied动作与 Views/Account/AccessDenied.cshtml 则对应授权失败例如角色不满足时的兜底页面由AccessDeniedPath配置驱动。查看 Claims 与认证票据Views/Home/MyClaims.cshtml 是验证整个链路成果的窗口using Microsoft.AspNetCore.Authentication h2HttpContext.User.Claims/h2 dl foreach (var claim in User.Claims) { dtclaim.Type/dt ddclaim.Value/dd } /dl h2AuthenticationProperties/h2 dl foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items) { dtprop.Key/dt ddprop.Value/dd } /dl上半部分遍历User.Claims登录后你会看到user值即输入的用户名与roleMember两个自定义 Claims下半部分调用Context.AuthenticateAsync()获取AuthenticationResult再读取其Properties.Items——这里能看到CookieAuthenticationHandler写入票据时的元数据例如IsPersistent是否持久化、ExpiresUtc过期时间等便于排查为什么 Cookie 一会就失效之类的问题。登出AccountController.Logout是对称的清理动作public async TaskIActionResult Logout() { await HttpContext.SignOutAsync(); return Redirect(/); }SignOutAsync同样使用默认方案底层由CookieAuthenticationHandler删除客户端 Cookie之后再次访问受保护页面又会被重定向到登录页。请求管道中的认证中间件顺序Startup.Configure中中间件的注册顺序对认证功能至关重要Startup.csapp.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints { endpoints.MapDefaultControllerRoute(); });UseAuthentication必须位于UseAuthorization之前前者负责解析请求中的 Cookie 并填充HttpContext.User后者配合[Authorize]基于User做授权决策顺序颠倒会导致授权永远失败UseRouting在认证之前这是较新版本 ASP.NET Core 的推荐顺序认证中间件可以拿到端点元数据如允许匿名访问的端点UseStaticFiles放在认证之前静态资源不经过身份校验即可访问开发环境启用UseDeveloperExceptionPage生产环境回退到UseExceptionHandler(/Home/Error)与 Views/Shared/Error.cshtml 配合输出错误页。底层原理速览从源码结构看Cookie 认证的核心实现在 src/Security/Authentication/Cookies/src其中 CookieAuthenticationHandler.cs 完成了以下关键工作HandleAuthenticateAsync从请求中取出 Cookie调用 DataProtection 解密并反序列化AuthenticationTicket校验过期时间后重建ClaimsPrincipal失败或过期则视为未认证HandleSignInAsync把传入的ClaimsPrincipal与AuthenticationProperties序列化、加密后写入响应 Cookie并可依据属性设置持久化与过期时间HandleSignOutAsync下发过期 Cookie 使客户端票据失效。这些机制解释了示例中登录后访问 MyClaims 无需再输入密码、重启浏览器仍可能保持登录等现象也提示了CookieAuthenticationOptions中Cookie.Expiration、ExpireTimeSpan、SlidingExpiration等配置项的实际作用点——它们都在这份处理器源码中被消费。运行方式在仓库根目录或示例目录下使用 .NET SDK 运行即可# 在示例目录下 dotnet run --project src/Security/samples/Cookies启动后浏览器打开应用依次执行点击 MyClaims → 被重定向到登录页 → 输入任意用户名与密码提交 → 回到 MyClaims 查看 Claims 列表。若需修改端口可参考 Properties/launchSettings.json。小结通过这个最小示例可以清晰看到 ASP.NET Core Cookie 认证的完整闭环AddAuthentication AddCookie完成方案注册与默认方案设定LoginPath/AccessDeniedPath控制未认证与未授权的跳转AccountController手工构造 Claims 并调用SignInAsync签发身份[Authorize]保护端点SignOutAsync清理会话MyClaims视图则把还原出的 Claims 与票据属性直观呈现出来。无论是接入 Identity 还是自建认证体系这套 Cookie 方案的注册、配置与管道顺序都是最底层、最通用的地基。【免费下载链接】aspnetcoreASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.项目地址: https://gitcode.com/GitHub_Trending/as/aspnetcore创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考