예제 #1
0
        internal static JwtHeader ReadJwtHeaderSlow(ref Utf8JsonReader reader)
        {
            var current = new JwtObject(3);
            var header  = new JwtHeader(current);

            while (reader.Read())
            {
                if (!(reader.TokenType is JsonTokenType.PropertyName))
                {
                    break;
                }

                if (reader.ValueTextEquals(HeaderParameters.AlgUtf8) && reader.Read())
                {
                    if (!(reader.TokenType is JsonTokenType.String))
                    {
                        break;
                    }

                    var alg = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
                    if (SignatureAlgorithm.TryParse(alg, out var signatureAlgorithm))
                    {
                        header.SignatureAlgorithm = signatureAlgorithm;
                    }
                    else if (KeyManagementAlgorithm.TryParse(alg, out var keyManagementAlgorithm))
                    {
                        header.KeyManagementAlgorithm = keyManagementAlgorithm;
                    }
                    else if (SignatureAlgorithm.TryParseSlow(ref reader, out signatureAlgorithm))
                    {
                        header.SignatureAlgorithm = signatureAlgorithm;
                    }
                    else if (KeyManagementAlgorithm.TryParseSlow(ref reader, out keyManagementAlgorithm))
                    {
                        header.KeyManagementAlgorithm = keyManagementAlgorithm;
                    }
                    else
                    {
                        // TODO : Fix when the Utf8JsonReader will allow
                        // to read an unescaped string without allocating a string
                        current.Add(new JwtProperty(WellKnownProperty.Alg, Encoding.UTF8.GetBytes(reader.GetString())));
                    }
                }
                else if (reader.ValueTextEquals(HeaderParameters.EncUtf8) && reader.Read())
                {
                    if (!(reader.TokenType is JsonTokenType.String))
                    {
                        break;
                    }

                    var enc = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
                    if (EncryptionAlgorithm.TryParse(enc, out var encryptionAlgorithm))
                    {
                        header.EncryptionAlgorithm = encryptionAlgorithm;
                    }
                    else if (EncryptionAlgorithm.TryParseSlow(ref reader, out encryptionAlgorithm))
                    {
                        header.EncryptionAlgorithm = encryptionAlgorithm;
                    }
                    else
                    {
                        // TODO : Fix when the Utf8JsonReader will allow
                        // to read an unescaped string without allocating a string
                        current.Add(new JwtProperty(WellKnownProperty.Enc, Encoding.UTF8.GetBytes(reader.GetString())));
                    }
                }
                else if (reader.ValueTextEquals(HeaderParameters.CtyUtf8) && reader.Read())
                {
                    if (!(reader.TokenType is JsonTokenType.String))
                    {
                        break;
                    }

                    current.Add(new JwtProperty(WellKnownProperty.Cty, Encoding.UTF8.GetBytes(reader.GetString())));
                }
                else if (reader.ValueTextEquals(HeaderParameters.TypUtf8) && reader.Read())
                {
                    if (!(reader.TokenType is JsonTokenType.String))
                    {
                        break;
                    }

                    current.Add(new JwtProperty(WellKnownProperty.Typ, Encoding.UTF8.GetBytes(reader.GetString())));
                }
                else if (reader.ValueTextEquals(HeaderParameters.KidUtf8) && reader.Read())
                {
                    if (!(reader.TokenType is JsonTokenType.String))
                    {
                        break;
                    }

                    current.Add(new JwtProperty(WellKnownProperty.Kid, reader.GetString()));
                }
                else if (reader.ValueTextEquals(HeaderParameters.ZipUtf8) && reader.Read())
                {
                    if (!(reader.TokenType is JsonTokenType.String))
                    {
                        break;
                    }

                    var zip = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
                    if (CompressionAlgorithm.TryParse(zip, out var compressionAlgorithm))
                    {
                        current.Add(new JwtProperty(compressionAlgorithm));
                    }
                    else if (CompressionAlgorithm.TryParseSlow(ref reader, out compressionAlgorithm))
                    {
                        current.Add(new JwtProperty(compressionAlgorithm));
                    }
                    else
                    {
                        // TODO : Fix when the Utf8JsonReader will allow
                        // to read an unescaped string without allocating a string
                        current.Add(new JwtProperty(WellKnownProperty.Zip, Encoding.UTF8.GetBytes(reader.GetString())));
                    }
                }
                else
                {
                    var name = reader.GetString();
                    reader.Read();
                    switch (reader.TokenType)
                    {
                    case JsonTokenType.StartObject:
                        current.Add(name, JsonParser.ReadJsonObject(ref reader));
                        break;

                    case JsonTokenType.StartArray:
                        current.Add(name, JsonParser.ReadJsonArray(ref reader));
                        break;

                    case JsonTokenType.String:
                        current.Add(name, reader.GetString());
                        break;

                    case JsonTokenType.True:
                        current.Add(name, true);
                        break;

                    case JsonTokenType.False:
                        current.Add(name, false);
                        break;

                    case JsonTokenType.Null:
                        current.Add(name);
                        break;

                    case JsonTokenType.Number:
                        if (reader.TryGetInt64(out long longValue))
                        {
                            current.Add(name, longValue);
                        }
                        else
                        {
                            if (reader.TryGetDouble(out double doubleValue))
                            {
                                current.Add(name, doubleValue);
                            }
                            else
                            {
                                throw new FormatException($"NotSupportedNumberValue {Encoding.UTF8.GetBytes(name)}");
                            }
                        }
                        break;

                    default:
                        throw new FormatException("MalformedJson");
                    }
                }
            }

            if (!(reader.TokenType is JsonTokenType.EndObject))
            {
                throw new FormatException("MalformedJson");
            }

            return(header);
        }