C# 序列化 JWT 负载输出不正确的数据

huangapple go评论66阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年3月31日 15:53:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896109.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定