diff --git a/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs b/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs
index 89768d6d53c5..3a72df17bda8 100644
--- a/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs
+++ b/src/Http/Authentication.Abstractions/src/AuthenticationProperties.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Text.Json.Serialization;
namespace Microsoft.AspNetCore.Authentication
{
@@ -30,6 +31,7 @@ public AuthenticationProperties()
/// Initializes a new instance of the class.
///
/// State values dictionary to use.
+ [JsonConstructor]
public AuthenticationProperties(IDictionary items)
: this(items, parameters: null)
{ }
diff --git a/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs b/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs
index c511208a3c53..e486ce3255a7 100644
--- a/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs
+++ b/src/Http/Authentication.Core/test/AuthenticationPropertiesTests.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text.Json;
using Xunit;
namespace Microsoft.AspNetCore.Authentication.Core.Test
@@ -302,6 +303,42 @@ public void GetBool()
Assert.Equal("BAR", props.Items["foo"]);
}
+ [Fact]
+ public void Roundtrip_Serializes_With_SystemTextJson()
+ {
+ var props = new AuthenticationProperties()
+ {
+ AllowRefresh = true,
+ ExpiresUtc = new DateTimeOffset(2021, 03, 28, 13, 47, 00, TimeSpan.Zero),
+ IssuedUtc = new DateTimeOffset(2021, 03, 28, 12, 47, 00, TimeSpan.Zero),
+ IsPersistent = true,
+ RedirectUri = "/foo/bar"
+ };
+
+ props.Items.Add("foo", "bar");
+
+ props.Parameters.Add("baz", "quux");
+
+ var json = JsonSerializer.Serialize(props);
+ var deserialized = JsonSerializer.Deserialize(json);
+
+ Assert.NotNull(deserialized);
+
+ Assert.Equal(props.AllowRefresh, deserialized!.AllowRefresh);
+ Assert.Equal(props.ExpiresUtc, deserialized.ExpiresUtc);
+ Assert.Equal(props.IssuedUtc, deserialized.IssuedUtc);
+ Assert.Equal(props.IsPersistent, deserialized.IsPersistent);
+ Assert.Equal(props.RedirectUri, deserialized.RedirectUri);
+
+ Assert.NotNull(deserialized.Items);
+ Assert.True(deserialized.Items.ContainsKey("foo"));
+ Assert.Equal(props.Items["foo"], deserialized.Items["foo"]);
+
+ // Ensure that parameters are not round-tripped
+ Assert.NotNull(deserialized.Parameters);
+ Assert.Equal(0, deserialized.Parameters.Count);
+ }
+
public class MyAuthenticationProperties : AuthenticationProperties
{
public new DateTimeOffset? GetDateTimeOffset(string key)