-
Notifications
You must be signed in to change notification settings - Fork 456
Expand file tree
/
Copy pathJsonWebToken.HeaderClaimSet.cs
More file actions
117 lines (108 loc) · 5.41 KB
/
JsonWebToken.HeaderClaimSet.cs
File metadata and controls
117 lines (108 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Text.Json;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.Tokens.Json;
namespace Microsoft.IdentityModel.JsonWebTokens
{
public partial class JsonWebToken
{
internal JsonClaimSet CreateHeaderClaimSet(byte[] bytes)
{
return CreateHeaderClaimSet(bytes.AsSpan());
}
internal JsonClaimSet CreateHeaderClaimSet(byte[] bytes, int length)
{
return CreateHeaderClaimSet(bytes.AsSpan(0, length));
}
internal JsonClaimSet CreateHeaderClaimSet(ReadOnlySpan<byte> byteSpan)
{
Utf8JsonReader reader = new(byteSpan);
if (!JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.StartObject, true))
throw LogHelper.LogExceptionMessage(
new JsonException(
LogHelper.FormatInvariant(
Tokens.LogMessages.IDX11023,
LogHelper.MarkAsNonPII("JsonTokenType.StartObject"),
LogHelper.MarkAsNonPII(reader.TokenType),
LogHelper.MarkAsNonPII(ClassName),
LogHelper.MarkAsNonPII(reader.TokenStartIndex),
LogHelper.MarkAsNonPII(reader.CurrentDepth),
LogHelper.MarkAsNonPII(reader.BytesConsumed))));
Dictionary<string, object> claims = new();
while (true)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
ReadHeaderValue(ref reader, claims);
}
// We read a JsonTokenType.StartObject above, exiting and positioning reader at next token.
else if (JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.EndObject, false))
break;
else if (!reader.Read())
break;
}
return new JsonClaimSet(claims);
}
/// <summary>
/// Reads the value of a claim in the header and adds it to the <paramref name="claims"/> dictionary.
/// Can be overridden to read and add custom claims.
/// If a custom claim is read, the reader should be positioned at the next token after reading the claim.
/// </summary>
/// <param name="reader">The Utf8JsonReader instance positioned at a claim name token used to read the JSON payload.</param>
/// <param name="claims">Collection of claims that have been read from the reader.</param>
private protected virtual void ReadHeaderValue(ref Utf8JsonReader reader, IDictionary<string, object> claims)
{
if (reader.ValueTextEquals(JwtHeaderUtf8Bytes.Alg))
{
claims[JwtHeaderParameterNames.Alg] = JsonSerializerPrimitives.ReadString(ref reader, JwtHeaderParameterNames.Alg, ClassName, true);
}
else if (reader.ValueTextEquals(JwtHeaderUtf8Bytes.Cty))
{
claims[JwtHeaderParameterNames.Cty] = JsonSerializerPrimitives.ReadString(ref reader, JwtHeaderParameterNames.Cty, ClassName, true);
}
else if (reader.ValueTextEquals(JwtHeaderUtf8Bytes.Kid))
{
claims[JwtHeaderParameterNames.Kid] = JsonSerializerPrimitives.ReadString(ref reader, JwtHeaderParameterNames.Kid, ClassName, true);
}
else if (reader.ValueTextEquals(JwtHeaderUtf8Bytes.Typ))
{
claims[JwtHeaderParameterNames.Typ] = JsonSerializerPrimitives.ReadString(ref reader, JwtHeaderParameterNames.Typ, ClassName, true); ;
}
else if (reader.ValueTextEquals(JwtHeaderUtf8Bytes.X5t))
{
claims[JwtHeaderParameterNames.X5t] = JsonSerializerPrimitives.ReadString(ref reader, JwtHeaderParameterNames.X5t, ClassName, true);
}
else if (reader.ValueTextEquals(JwtHeaderUtf8Bytes.Zip))
{
claims[JwtHeaderParameterNames.Zip] = JsonSerializerPrimitives.ReadString(ref reader, JwtHeaderParameterNames.Zip, ClassName, true);
}
else
{
string claimName = reader.GetString();
if (TryReadJwtClaim != null)
{
reader.Read(); // Move to the value
if (TryReadJwtClaim(ref reader, JwtSegmentType.Header, claimName, out object claimValue))
{
claims[claimName] = claimValue;
reader.Read(); // Move to the next token
}
else
{
// The reader is positioned at the value token. The custom delegate did not read the value. Use our own logic.
claims[claimName] = JsonSerializerPrimitives.ReadPropertyValueAsObject(ref reader, claimName, JsonClaimSet.ClassName, false);
}
}
else
{
// Move the reader forward to the value and read it using our own logic.
claims[claimName] = JsonSerializerPrimitives.ReadPropertyValueAsObject(ref reader, claimName, JsonClaimSet.ClassName, true);
}
}
}
}
}