英文:
C# Serializing JWT payload outputs incorrect data
问题
验证 JWT 后,我需要将其 payload 作为 JSON 获取,并对 JSON 输出执行一些令牌后验证处理,将其发送为消息到另一个服务,问题是 scope
字段的输出不正确。序列化库是 Newtonsoft。
它应该被序列化为 "scope":["scope1","scope2"]
,但实际上它输出为 "scope":[[],[]]
,我检查了令牌本身,它确实包含字符串值,并且数据类型正确。
代码:
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}
).AddJwtBearer(opt =>
{
var validationParams = TokenValidatorHandler.ValidationParameters();
//opt.Authority = "http://localhost";
opt.RequireHttpsMetadata = false;
opt.TokenValidationParameters = validationParams;
opt.SecurityTokenValidators.Clear(); // clear all existing token validators
opt.SecurityTokenValidators.Add(new JwtSecurityTokenHandler()); // add JwtSecurityTokenHandler as the only token validator
opt.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
string token = ((JwtSecurityToken)context.SecurityToken).RawData;
TokenValidatorHandler.ParseToken(token);
return Task.CompletedTask;
}
};
});
解析令牌:
public static void ParseToken(string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var validatedToken = tokenHandler.ReadJwtToken(token);
var payloadJSON = JsonConvert.SerializeObject(validatedToken.Payload);
// perform sending the token and other operations
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
英文:
After validating the JWT i need to get its payload as JSON and perform some post token validation processing on the JSON output itself by sending it as a messsage to another service the problem is the output of the scope
field is incorrect. The serialization lib is Newtonsoft
It should be serialized as "scope":["scope1","scope2"]
but instead its outputting "scope":[[],[]]
and i checked the token itself, and it does contain string values and is of the correct data type
Code :
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}
).AddJwtBearer(opt =>
{
var validationParams = TokenValidatorHandler.ValidationParameters();
//opt.Authority = "http://localhost";
opt.RequireHttpsMetadata = false;
opt.TokenValidationParameters = validationParams;
opt.SecurityTokenValidators.Clear(); // clear all existing token validators
opt.SecurityTokenValidators.Add(new JwtSecurityTokenHandler()); // add JwtSecurityTokenHandler as the only token validator
opt.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
string token = ((JwtSecurityToken)context.SecurityToken).RawData;
TokenValidatorHandler.ParseToken(token);
return Task.CompletedTask;
}
};
});`
Parsing the token :
public static void ParseToken(string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var validatedToken = tokenHandler.ReadJwtToken(token);
var payloadJSON = JsonConvert.SerializeObject(validatedToken.Payload);
// perform sending the token and other operations
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}`
答案1
得分: 0
我已解决了这个问题,对于使用Microsoft.IdentityModel.Tokens的任何人来说,问题出在“scope”数组内的数据类型,出于某种原因它没有被解析为字符串,而是一些其他数据类型,解决方法是手动将它转换为字符串数组:
//使用tokenHandler读取令牌
var clms = validatedToken.Claims.Where(x => x.Type == "scope").ToList();
validatedToken.Payload["scope"] = clms.Select(x => x.Value).ToArray();
这修复了不正确的数据类型,并输出了预期的数组。
英文:
I have solved the issue, for anyone using Microsoft.IdentityModel.Tokens
the problem was with the data type inside the "scope" array for whatever reason it was not being Parsed as string but some other data type, the solution is to convert it to a string array manually :
//read the token using the tokenHandler
var clms = validatedToken.Claims.Where(x => x.Type == "scope").ToList();
validatedToken.Payload["scope"] = clms.Select(x => x.Value).ToArray();
this fixed the incorrect datatype and outputs the expected array
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论