Skip to content

Commit acfb162

Browse files
authored
[HttpWorker]Fix identities serialization (#5459)
1 parent 29f0a02 commit acfb162

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/WebJobs.Script/Extensions/HttpRequestExtensions.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Linq;
77
using System.Net.Http.Headers;
8+
using System.Security.Claims;
89
using System.Threading.Tasks;
910
using Microsoft.AspNetCore.Http;
1011
using Microsoft.AspNetCore.Http.Extensions;
@@ -110,7 +111,7 @@ public static bool IsMediaTypeOctetOrMultipart(this HttpRequest request)
110111
public static async Task<JObject> GetRequestAsJObject(this HttpRequest request)
111112
{
112113
var jObjectHttp = new JObject();
113-
jObjectHttp["Url"] = $"{(request.IsHttps ? "https" : "http")}://{request.Host.ToString()}{request.Path.ToString()}{request.QueryString.ToString()}"; // [http|https]://{url}{path}{query}
114+
jObjectHttp["Url"] = $"{(request.IsHttps ? "https" : "http")}://{request.Host.ToString()}{request.Path.ToString()}{request.QueryString.ToString()}";
114115
jObjectHttp["Method"] = request.Method.ToString();
115116
if (request.Query != null)
116117
{
@@ -131,7 +132,7 @@ public static async Task<JObject> GetRequestAsJObject(this HttpRequest request)
131132

132133
if (request.HttpContext?.User?.Identities != null)
133134
{
134-
jObjectHttp["Identities"] = JsonConvert.SerializeObject(request.HttpContext.User.Identities);
135+
jObjectHttp["Identities"] = GetUserIdentitiesAsString(request.HttpContext.User.Identities);
135136
}
136137

137138
// parse request body as content-type
@@ -165,5 +166,14 @@ internal static IDictionary<string, string> GetQueryCollectionAsDictionary(this
165166
}
166167
return queryParamsDictionary;
167168
}
169+
170+
internal static string GetUserIdentitiesAsString(IEnumerable<ClaimsIdentity> claimsIdentities)
171+
{
172+
return JsonConvert.SerializeObject(claimsIdentities, new JsonSerializerSettings
173+
{
174+
// Claims property in Identities had circular reference to property 'Subject'
175+
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
176+
});
177+
}
168178
}
169179
}

test/WebJobs.Script.Tests/Extensions/HttpRequestExtensionsTest.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Security.Claims;
7+
using System.Security.Principal;
68
using System.Text;
79
using Microsoft.AspNetCore.Http;
810
using Microsoft.Azure.WebJobs.Script.Config;
@@ -39,5 +41,27 @@ public void IsAppServiceInternalRequest_ReturnsExpectedResult()
3941
Assert.True(request.IsAppServiceInternalRequest());
4042
}
4143
}
44+
45+
[Fact]
46+
public void ConvertUserIdentitiesToString_RemovesCircularReference()
47+
{
48+
string expectedUserIdentities = "[{\"AuthenticationType\":\"TestAuthType\",\"IsAuthenticated\":true";
49+
IIdentity identity = new TestIdentity();
50+
Claim claim = new Claim("authlevel", "admin", "test", "LOCAL AUTHORITY", "LOCAL AUTHORITY");
51+
List<Claim> claims = new List<Claim>() { claim };
52+
ClaimsIdentity claimsIdentity = new ClaimsIdentity(identity, claims);
53+
List<ClaimsIdentity> claimsIdentities = new List<ClaimsIdentity>() { claimsIdentity };
54+
string userIdentitiesString = HttpRequestExtensions.GetUserIdentitiesAsString(claimsIdentities);
55+
Assert.Contains(expectedUserIdentities, userIdentitiesString);
56+
}
57+
}
58+
59+
internal class TestIdentity : IIdentity
60+
{
61+
public string AuthenticationType => "TestAuthType";
62+
63+
public bool IsAuthenticated => true;
64+
65+
public string Name => "TestIdentityName";
4266
}
4367
}

0 commit comments

Comments
 (0)