.NET Core中Claim的核心作用详解及AddScreaningHandler获取Claim信息方法
.NET Core Claim核心作用及Claim Principal信息提取方案
一、Claim核心作用
- Claim是.NET Core身份体系中最小的身份信息单元,本质是声明式的键值对,用来存储当前用户的各类身份、业务属性,比如用户ID、所属公司ID、角色、邮箱、手机号等,来源于身份签发方(比如JWT服务、Cookie认证服务),默认不可篡改
- 多个Claim组成ClaimsIdentity(身份凭证,可类比为一张身份证),多个ClaimsIdentity组成ClaimsPrincipal(用户主体,可类比为一个人可能同时持有身份证、驾驶证多个有效凭证)
- 授权场景中可以直接基于Claim做权限校验,不需要额外查数据库拉取用户基础信息,减少数据库IO,提升授权效率
二、从ClaimsPrincipal提取信息的通用方法
你当前代码中调用的HasClaim方法仅用来判断是否存在对应类型的Claim,返回布尔值,无法获取Claim的实际值,正确的取值方式如下:
- 单个值提取:用
FindFirstValue快捷方法,直接传入Claim的Type即可返回对应值,无需手动遍历Claim集合 - 批量提取:可以将所有Claim转换为字典,方便批量取值
- 注意:Claim存储的值默认都是字符串类型,需要转成对应业务类型(比如int、Guid)时要做类型转换和空校验,避免空引用异常
三、AddScreaningHandler优化实现
根据你调试截图的Claim结构,用户ID对应Type为id,公司ID对应Type为companyId,优化后的代码如下:
public class AddScreaningHandler : AuthorizationHandler<AddScreaning> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AddScreaning requirement) { // 1. 快捷提取所需Claim值 string userIdStr = context.User.FindFirstValue("id"); string userCompanyIdStr = context.User.FindFirstValue("companyId"); // 2. 基础空校验,避免Claim缺失导致异常 if (string.IsNullOrEmpty(userIdStr) || string.IsNullOrEmpty(userCompanyIdStr)) { context.Fail(); return Task.CompletedTask; } // 3. 转换为业务需要的类型,示例转Guid,可根据实际业务换int等类型 if (!Guid.TryParse(userIdStr, out Guid userId) || !Guid.TryParse(userCompanyIdStr, out Guid userCompanyId)) { context.Fail(); return Task.CompletedTask; } // 4. 业务校验逻辑示例:校验当前用户的公司ID和提交的筛查数据所属公司ID是否匹配 if (context.Resource is AuthorizationFilterContext mvcContext) { // 从请求上下文拿到接口传入的参数 if (mvcContext.ActionArguments["createScreeningDto"] is CreateScreeningDto dto) { if (dto.companyId != userCompanyId) { // 公司ID不匹配,授权失败 context.Fail(); return Task.CompletedTask; } } else { context.Fail(); return Task.CompletedTask; } } // 所有校验通过,标记授权成功 context.Succeed(requirement); return Task.CompletedTask; } }
提示:如果你使用.NET 6+内置的JWT认证,也可以直接用系统预设的
ClaimTypes.NameIdentifier(对应标准用户ID)、ClaimTypes.Role(对应角色)等枚举值作为ClaimType,和自定义Type用法完全一致。
内容的提问来源于stack exchange,提问作者junior
相关产品推荐
相关产品推荐

