一个用户点击登录按钮后,系统背后发生了什么?这不是魔法,而是一套精密的流水线作业。ASP.NET Core的饼干认证机制,把"你是谁"和"你能做什么"拆成了两道独立关卡,每道关卡都有明确的岗位职责。
第一道关卡叫认证(Authentication),解决身份问题。开发者在Program.cs里这样配置:
![]()
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => { options.LoginPath = "/Account/Login"; options.AccessDeniedPath = "/Account/AccessDenied"; options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.SlidingExpiration = true; });
AddAuthentication把认证服务注册到依赖注入容器,同时指定默认方案为Cookies。AddCookie则提供具体的饼干处理程序,负责加密、解密和验证那块存储用户身份的小文件。LoginPath指向登录页,AccessDeniedPath处理权限不足的情况,ExpireTimeSpan设为60分钟,SlidingExpiration开启后,用户活跃时饼干会自动续期。
第二道关卡叫授权(Authorization),解决权限问题。代码同样简洁:
builder.Services.AddAuthorization(options => { options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin").RequireClaim("EmployeeId")); });
这里定义了一条名为"AdminOnly"的策略:用户必须同时拥有Admin角色,以及EmployeeId声明。授权服务会拿着这些规则,去核对用户身份凭证上的每一项信息。
当请求真正进入管道,故事才刚开始。首先调用app.UseAuthentication(),认证中间件开始工作。它向认证服务索要一个ClaimsPrincipal对象,认证服务转交给饼干处理程序。处理程序用数据保护提供程序(Data Protection Provider)解密饼干,从中提取用户信息,构造出ClaimsPrincipal,然后挂到HttpContext.User上。此时请求才继续流向下一环。
紧接着app.UseAuthorization()登场。授权中间件检查端点是否打了[Authorize]标签,或者指定了具体策略如[Authorize(Policy = "AdminOnly")]。它把ClaimsPrincipal交给授权服务,逐项比对策略要求。
比对结果分三路走。如果策略需要用户但未登录,系统触发Challenge,把用户踢到登录页。如果已登录但声明不满足,触发Forbid,导向拒绝访问页。只有全部过关,请求才能抵达控制器方法。
这套设计的妙处在于解耦。认证只管"这人是不是他自称的那个人",授权只管"这人有没有资格干这件事"。两块逻辑独立演化,测试时可以分别Mock,部署时也能灵活替换。比如认证从饼干换成JWT令牌,授权层代码完全不用动。
60分钟的过期窗口加上滑动续期,是平衡安全与体验的常见做法。太久不安全,太短烦用户。RequireClaim那条EmployeeId,则是业务系统的典型需求——光有角色不够,还得确认是内部员工账号。这些细节没有标准答案,取决于你的风险模型和用户容忍度。
理解这条流水线,调试时就不会迷茫。用户说"我明明登录了却看不到页面",先查认证中间件有没有跑,饼干还在不在。如果说"我能登录但按钮点不了",问题在授权策略,看ClaimsPrincipal里缺了哪条声明。工具链清晰,排障才有章法。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.