Skip to content

Commit 306b210

Browse files
keegan-carusoKeegan Caruso
andauthored
Move CNF from SHR to M.IM.Tokens (#3168)
* Move CNF from SHR to Tokens, move to public --------- Co-authored-by: Keegan Caruso <[email protected]>
1 parent 9d007d8 commit 306b210

8 files changed

Lines changed: 246 additions & 79 deletions

File tree

Lines changed: 5 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,19 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
using System;
5-
using System.Text;
6-
using System.Text.Json;
7-
using System.Text.Json.Serialization;
8-
using Microsoft.IdentityModel.Logging;
9-
using Microsoft.IdentityModel.Tokens;
10-
using Microsoft.IdentityModel.Tokens.Json;
11-
124
namespace Microsoft.IdentityModel.Protocols.SignedHttpRequest
135
{
146
/// <summary>
157
/// Represents the Cnf Claim
168
/// </summary>
17-
internal class Cnf
9+
internal class Cnf : Tokens.Cnf
1810
{
19-
internal const string ClassName = "Microsoft.IdentityModel.Protocols.SignedHttpRequest.Cnf";
20-
21-
public Cnf() { }
22-
23-
public Cnf(string json)
11+
public Cnf() : base()
2412
{
25-
if (string.IsNullOrEmpty(json))
26-
throw LogHelper.LogArgumentNullException(nameof(json));
27-
28-
Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json).AsSpan());
29-
if (!JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.StartObject, true))
30-
throw LogHelper.LogExceptionMessage(
31-
new JsonException(
32-
LogHelper.FormatInvariant(
33-
Tokens.LogMessages.IDX11023,
34-
LogHelper.MarkAsNonPII("JsonTokenType.StartObject"),
35-
LogHelper.MarkAsNonPII(reader.TokenType),
36-
LogHelper.MarkAsNonPII(ClassName),
37-
LogHelper.MarkAsNonPII(reader.TokenStartIndex),
38-
LogHelper.MarkAsNonPII(reader.CurrentDepth),
39-
LogHelper.MarkAsNonPII(reader.BytesConsumed))));
40-
41-
while (true)
42-
{
43-
if (reader.TokenType == JsonTokenType.PropertyName)
44-
{
45-
if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Jwk))
46-
{
47-
reader.Read();
48-
JsonWebKey = JsonWebKeySerializer.Read(ref reader, new JsonWebKey());
49-
}
50-
else if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Kid))
51-
{
52-
Kid = JsonSerializerPrimitives.ReadString(ref reader, ConfirmationClaimTypes.Kid, ClassName, true);
53-
}
54-
else if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Jku))
55-
{
56-
Jku = JsonSerializerPrimitives.ReadString(ref reader, ConfirmationClaimTypes.Kid, ClassName, true);
57-
}
58-
else if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Jwe))
59-
{
60-
Jwe = JsonSerializerPrimitives.ReadString(ref reader, ConfirmationClaimTypes.Jwe, ClassName, true);
61-
}
62-
else
63-
{
64-
// this is not a property we recognize, skip it.
65-
reader.Skip();
66-
}
67-
}
68-
// We read a JsonTokenType.StartObject above, exiting and positioning reader at next token.
69-
else if (JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.EndObject, true))
70-
break;
71-
else if (!reader.Read())
72-
break;
73-
}
7413
}
7514

76-
[JsonPropertyName("kid")]
77-
public string Kid { get; set; }
78-
79-
[JsonPropertyName("jwe")]
80-
public string Jwe { get; set; }
81-
82-
[JsonPropertyName("jku")]
83-
public string Jku { get; set; }
84-
85-
[JsonPropertyName("jwk")]
86-
public JsonWebKey JsonWebKey { get; set; }
15+
public Cnf(string json) : base(json)
16+
{
17+
}
8718
}
8819
}

src/Microsoft.IdentityModel.Protocols.SignedHttpRequest/ConfirmationClaimTypes.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,27 @@ public static class ConfirmationClaimTypes
1414
/// <summary>
1515
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.1.1
1616
/// </summary>
17-
public const string Cnf = "cnf";
17+
public const string Cnf = Tokens.ConfirmationClaimTypes.Cnf;
1818

1919
/// <summary>
2020
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
2121
/// </summary>
22-
public const string Jwk = "jwk";
22+
public const string Jwk = Tokens.ConfirmationClaimTypes.Jwk;
2323

2424
/// <summary>
2525
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
2626
/// </summary>
27-
public const string Jwe = "jwe";
27+
public const string Jwe = Tokens.ConfirmationClaimTypes.Jwe;
2828

2929
/// <summary>
3030
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
3131
/// </summary>
32-
public const string Jku = "jku";
32+
public const string Jku = Tokens.ConfirmationClaimTypes.Jku;
3333

3434
/// <summary>
3535
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
3636
/// </summary>
37-
public const string Kid = "kid";
37+
public const string Kid = Tokens.ConfirmationClaimTypes.Kid;
3838
}
3939

4040
internal static class ConfirmationClaimTypesUtf8Bytes
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Text;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
using Microsoft.IdentityModel.Logging;
9+
using Microsoft.IdentityModel.Tokens.Json;
10+
11+
namespace Microsoft.IdentityModel.Tokens
12+
{
13+
/// <summary>
14+
/// Represents the Cnf Claim
15+
/// </summary>
16+
public class Cnf
17+
{
18+
/// <summary>
19+
/// The class name used for logging and exception messages.
20+
/// </summary>
21+
internal string ClassName { get; }
22+
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="Cnf"/> class.
25+
/// </summary>
26+
public Cnf()
27+
{
28+
// GetType returns the runtime type, e.g. if derived,
29+
// it will return the derived type.
30+
ClassName = GetType().FullName;
31+
}
32+
33+
/// <summary>
34+
/// Initializes a new instance of the <see cref="Cnf"/> class.
35+
/// </summary>
36+
/// <param name="json">
37+
/// JSON representation of the Cnf Claim.
38+
/// </param>
39+
public Cnf(string json) : this()
40+
{
41+
if (string.IsNullOrEmpty(json))
42+
throw LogHelper.LogArgumentNullException(nameof(json));
43+
44+
Utf8JsonReader reader = new(Encoding.UTF8.GetBytes(json).AsSpan());
45+
if (!JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.StartObject, true))
46+
throw LogHelper.LogExceptionMessage(
47+
new JsonException(
48+
LogHelper.FormatInvariant(
49+
LogMessages.IDX11023,
50+
LogHelper.MarkAsNonPII("JsonTokenType.StartObject"),
51+
LogHelper.MarkAsNonPII(reader.TokenType),
52+
LogHelper.MarkAsNonPII(ClassName),
53+
LogHelper.MarkAsNonPII(reader.TokenStartIndex),
54+
LogHelper.MarkAsNonPII(reader.CurrentDepth),
55+
LogHelper.MarkAsNonPII(reader.BytesConsumed))));
56+
57+
while (true)
58+
{
59+
if (reader.TokenType == JsonTokenType.PropertyName)
60+
{
61+
if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Jwk))
62+
{
63+
reader.Read();
64+
JsonWebKey = JsonWebKeySerializer.Read(ref reader, new JsonWebKey());
65+
}
66+
else if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Kid))
67+
{
68+
Kid = JsonSerializerPrimitives.ReadString(ref reader, ConfirmationClaimTypes.Kid, ClassName, true);
69+
}
70+
else if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Jku))
71+
{
72+
Jku = JsonSerializerPrimitives.ReadString(ref reader, ConfirmationClaimTypes.Kid, ClassName, true);
73+
}
74+
else if (reader.ValueTextEquals(ConfirmationClaimTypesUtf8Bytes.Jwe))
75+
{
76+
Jwe = JsonSerializerPrimitives.ReadString(ref reader, ConfirmationClaimTypes.Jwe, ClassName, true);
77+
}
78+
else
79+
{
80+
// this is not a property we recognize, skip it.
81+
reader.Skip();
82+
}
83+
}
84+
// We read a JsonTokenType.StartObject above, exiting and positioning reader at next token.
85+
else if (JsonSerializerPrimitives.IsReaderAtTokenType(ref reader, JsonTokenType.EndObject, true))
86+
break;
87+
else if (!reader.Read())
88+
break;
89+
}
90+
}
91+
92+
/// <summary>
93+
/// The Kid property is used to specify the key ID of the public key used to verify the signature of the JWT.
94+
/// </summary>
95+
[JsonPropertyName("kid")]
96+
public string Kid { get; internal set; }
97+
98+
/// <summary>
99+
/// The Jwe property is used to specify an encrypted JSON web key.
100+
/// </summary>
101+
[JsonPropertyName("jwe")]
102+
public string Jwe { get; internal set; }
103+
104+
/// <summary>
105+
/// The Jku property is used to specify the location of the public key used to verify the signature of the JWT.
106+
/// </summary>
107+
[JsonPropertyName("jku")]
108+
public string Jku { get; internal set; }
109+
110+
/// <summary>
111+
/// The Jwk property is used to specify the public key used to verify the signature of the JWT.
112+
/// </summary>
113+
[JsonPropertyName("jwk")]
114+
public JsonWebKey JsonWebKey { get; internal set; }
115+
}
116+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
6+
namespace Microsoft.IdentityModel.Tokens
7+
{
8+
/// <summary>
9+
/// Confirmation Claim ("cnf") related constants
10+
/// https://datatracker.ietf.org/doc/html/rfc7800
11+
/// </summary>
12+
public static class ConfirmationClaimTypes
13+
{
14+
/// <summary>
15+
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.1.1
16+
/// </summary>
17+
public const string Cnf = "cnf";
18+
19+
/// <summary>
20+
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
21+
/// </summary>
22+
public const string Jwk = "jwk";
23+
24+
/// <summary>
25+
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
26+
/// </summary>
27+
public const string Jwe = "jwe";
28+
29+
/// <summary>
30+
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
31+
/// </summary>
32+
public const string Jku = "jku";
33+
34+
/// <summary>
35+
/// https://datatracker.ietf.org/doc/html/rfc7800#section-6.2.2
36+
/// </summary>
37+
public const string Kid = "kid";
38+
}
39+
40+
internal static class ConfirmationClaimTypesUtf8Bytes
41+
{
42+
public static ReadOnlySpan<byte> Cnf => "cnf"u8;
43+
public static ReadOnlySpan<byte> Jwk => "jwk"u8;
44+
public static ReadOnlySpan<byte> Jwe => "jwe"u8;
45+
public static ReadOnlySpan<byte> Jku => "jku"u8;
46+
public static ReadOnlySpan<byte> Kid => "kid"u8;
47+
}
48+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Microsoft.IdentityModel.Tokens.Cnf.Jku.set -> void
2+
Microsoft.IdentityModel.Tokens.Cnf.JsonWebKey.set -> void
3+
Microsoft.IdentityModel.Tokens.Cnf.Jwe.set -> void
4+
Microsoft.IdentityModel.Tokens.Cnf.Kid.set -> void
5+
Microsoft.IdentityModel.Protocols.SignedHttpRequest.ConfirmationClaimTypesUtf8Bytes
6+
Microsoft.IdentityModel.Tokens.Cnf.Jku.set -> void
7+
Microsoft.IdentityModel.Tokens.Cnf.JsonWebKey.set -> void
8+
Microsoft.IdentityModel.Tokens.Cnf.Jwe.set -> void
9+
Microsoft.IdentityModel.Tokens.Cnf.Kid.set -> void
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Microsoft.IdentityModel.Tokens.Cnf
2+
Microsoft.IdentityModel.Tokens.Cnf.Cnf() -> void
3+
Microsoft.IdentityModel.Tokens.Cnf.Cnf(string json) -> void
4+
Microsoft.IdentityModel.Tokens.Cnf.Jku.get -> string
5+
Microsoft.IdentityModel.Tokens.Cnf.JsonWebKey.get -> Microsoft.IdentityModel.Tokens.JsonWebKey
6+
Microsoft.IdentityModel.Tokens.Cnf.Jwe.get -> string
7+
Microsoft.IdentityModel.Tokens.Cnf.Kid.get -> string
8+
const Microsoft.IdentityModel.Tokens.ConfirmationClaimTypes.Cnf = "cnf" -> string
9+
const Microsoft.IdentityModel.Tokens.ConfirmationClaimTypes.Jku = "jku" -> string
10+
const Microsoft.IdentityModel.Tokens.ConfirmationClaimTypes.Jwe = "jwe" -> string
11+
const Microsoft.IdentityModel.Tokens.ConfirmationClaimTypes.Jwk = "jwk" -> string
12+
const Microsoft.IdentityModel.Tokens.ConfirmationClaimTypes.Kid = "kid" -> string
13+
Microsoft.IdentityModel.Tokens.ConfirmationClaimTypes
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Xunit;
5+
6+
namespace Microsoft.IdentityModel.Protocols.SignedHttpRequest.Tests
7+
{
8+
public class CnfTests
9+
{
10+
[Fact]
11+
public void CtorWithJson_ExpectedClassName()
12+
{
13+
var json = "{\"jwk\":{\"kty\":\"oct\",\"k\":\"AQIDBAUGBwgJCgsMDQ4PEC==\"}}";
14+
var cnf = new Cnf(json);
15+
Assert.Equal("Microsoft.IdentityModel.Protocols.SignedHttpRequest.Cnf", cnf.ClassName);
16+
}
17+
18+
[Fact]
19+
public void Ctor_ExpectedClassName()
20+
{
21+
var cnf = new Cnf();
22+
Assert.Equal("Microsoft.IdentityModel.Protocols.SignedHttpRequest.Cnf", cnf.ClassName);
23+
}
24+
}
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Xunit;
5+
6+
namespace Microsoft.IdentityModel.Tokens.Tests
7+
{
8+
public class CnfTests
9+
{
10+
[Fact]
11+
public void CtorWithJson_ExpectedClassName()
12+
{
13+
var json = "{\"jwk\":{\"kty\":\"oct\",\"k\":\"AQIDBAUGBwgJCgsMDQ4PEC==\"}}";
14+
var cnf = new Cnf(json);
15+
Assert.Equal("Microsoft.IdentityModel.Tokens.Cnf", cnf.ClassName);
16+
}
17+
18+
[Fact]
19+
public void Ctor_ExpectedClassName()
20+
{
21+
var cnf = new Cnf();
22+
Assert.Equal("Microsoft.IdentityModel.Tokens.Cnf", cnf.ClassName);
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)