0

0

C# JWT声明Claim操作方法 C#如何添加和读取JWT中的自定义声明

星降

星降

发布时间:2026-03-10 12:53:02

|

966人浏览过

|

来源于php中文网

原创

c#中jwt自定义声明操作需分五步:一、用jwtsecuritytokenhandler签发含自定义claim的jwt;二、解析jwtsecuritytoken提取声明;三、通过claimsprincipal在asp.net core中获取;四、用静态常量管理claim类型;五、对复杂对象先序列化再存入claim。

c# jwt声明claim操作方法 c#如何添加和读取jwt中的自定义声明

如果您在C#中使用JWT进行身份验证,需要向令牌中添加业务所需的自定义声明(Claim),或从已签发的JWT中安全提取这些声明,则需准确操作ClaimsIdentity与JwtSecurityToken结构。以下是实现此目标的具体方法:

一、使用JwtSecurityTokenHandler创建含自定义声明的JWT

该方法通过手动构建ClaimsIdentity并传入自定义Claim集合,再经JwtSecurityTokenHandler写入签名生成完整JWT字符串。适用于服务端签发令牌场景。

1、定义自定义声明集合,例如用户角色、部门ID、是否为VIP等:
var claims = new List
{
  new Claim(ClaimTypes.Name, "zhangsan"),
  new Claim("DepartmentId", "D001"),
  new Claim("IsVip", "true"),
  new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};

2、创建ClaimsIdentity实例,并将上述claims传入构造函数:
var identity = new ClaimsIdentity(claims, "JwtAuth");

3、配置SigningCredentials,使用对称密钥(如SymmetricSecurityKey)和签名算法(如HmacSha256):
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_32_byte_secret_key_here"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

4、构造JwtSecurityToken对象,指定Issuer、Audience、有效期及ClaimsIdentity:
var token = new JwtSecurityToken(
  issuer: "https://myapi.com",
  audience: "https://clientapp.com",
  claims: identity.Claims,
  expires: DateTime.UtcNow.AddMinutes(30),
  signingCredentials: creds
);

5、使用JwtSecurityTokenHandler.WriteToken()生成最终JWT字符串:
var handler = new JwtSecurityTokenHandler();
string jwtString = handler.WriteToken(token);

二、使用JwtSecurityToken直接解析并读取自定义声明

该方法适用于接收并验证外部传入的JWT字符串,从中提取原始Claim值。无需依赖HttpContext或AuthenticationManager,适合中间件或工具类场景。

1、实例化JwtSecurityTokenHandler:
var handler = new JwtSecurityTokenHandler();

2、调用ReadToken()方法解析JWT字符串,返回JwtSecurityToken对象:
var jwtToken = handler.ReadToken(jwtString) as JwtSecurityToken;

3、检查jwtToken是否为null且HasPayload,避免空引用异常:
if (jwtToken == null || !jwtToken.HasPayload)
  throw new ArgumentException(JWT字符串格式无效或无法解析);

4、遍历jwtToken.Payload.Claims集合,按Type匹配自定义声明:
var departmentId = jwtToken.Payload.Claims.FirstOrDefault(c => c.Type == "DepartmentId")?.Value;
var isVip = bool.TryParse(jwtToken.Payload.Claims.FirstOrDefault(c => c.Type == "IsVip")?.Value, out bool vipFlag) ? vipFlag : false;

5、对关键业务声明做存在性校验:
if (string.IsNullOrWhiteSpace(departmentId))
  throw new SecurityTokenException(缺少必需声明:DepartmentId);

三、通过ClaimsPrincipal从验证后的JWT中获取声明

该方法适用于ASP.NET Core中已启用JWT Bearer认证的上下文,系统自动将JWT载荷映射为ClaimsPrincipal,可直接访问User属性获取所有声明。

1、确保Startup.cs或Program.cs中已配置AddAuthentication().AddJwtBearer(),且TokenValidationParameters正确设置。

Jaaz
Jaaz

开源的AI设计智能体

下载

2、在Controller或Service中注入HttpContext或直接使用User属性:
var user = HttpContext.User;

3、使用FindFirst()方法查找单个自定义声明:
var deptClaim = user.FindFirst("DepartmentId");
string deptId = deptClaim?.Value;

4、使用Claims属性遍历全部声明并筛选:
var vipClaim = user.Claims.FirstOrDefault(c => c.Type == "IsVip");
bool isVip = vipClaim != null && bool.TryParse(vipClaim.Value, out bool flag) && flag;

5、强制要求特定声明存在时,可抛出未授权异常:
if (deptId == null)
  Context.Response.StatusCode = StatusCodes.Status401Unauthorized;
  throw new UnauthorizedAccessException(请求缺少有效DepartmentId声明);

四、使用JwtRegisteredClaimNames以外的常量注册自定义Claim类型

为避免硬编码字符串导致拼写错误或维护困难,建议将自定义Claim类型定义为静态只读字段,统一管理命名规范与语义。

1、在公共类中定义自定义Claim类型常量:
public static class CustomClaimTypes
{
  public const string DepartmentId = "DepartmentId";
  public const string IsVip = "IsVip";
  public const string TenantCode = "TenantCode";
}

2、添加声明时使用常量而非字符串字面量:
new Claim(CustomClaimTypes.DepartmentId, "D001");

3、读取声明时同样使用该常量:
user.FindFirst(CustomClaimTypes.DepartmentId)?.Value;

4、在策略授权(Policy-based Authorization)中引用该类型:
options.AddPolicy("InDepartment", policy => policy.RequireClaim(CustomClaimTypes.DepartmentId));

五、处理Claim值为复杂对象的序列化方式

当需嵌入JSON结构(如用户权限树、配置项集合)作为Claim值时,不能直接传入对象实例,必须先序列化为字符串,否则JwtSecurityToken构造过程会忽略或抛出异常。

1、准备要嵌入的对象,例如权限列表:
var permissions = new[] { "read:order", "write:product" };

2、使用System.Text.Json序列化为JSON字符串:
string jsonPermissions = JsonSerializer.Serialize(permissions);

3、将序列化后字符串作为Claim值添加:
new Claim("Permissions", jsonPermissions);

4、读取时反序列化回目标类型:
var permClaim = jwtToken.Payload.Claims.FirstOrDefault(c => c.Type == "Permissions");
if (permClaim != null)
  string[] perms = JsonSerializer.Deserialize(permClaim.Value);

5、捕获反序列化异常以防止令牌损坏导致服务中断:
try { ... } catch (JsonException ex) { throw new SecurityTokenException(Permissions声明内容非合法JSON格式, ex); }

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

182

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

226

2025.12.18

json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

454

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

546

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

334

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

253

2023.09.22

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号