Skip to content

Commit df4de7d

Browse files
Fixes emulating Entra auth for SPA apps (#1193)
1 parent d6930ae commit df4de7d

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

dev-proxy-plugins/Mocks/EntraMockResponsePlugin.cs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class EntraMockResponsePlugin(IPluginEvents pluginEvents, IProxyContext c
3939

4040
public override string Name => nameof(EntraMockResponsePlugin);
4141

42+
// Running on POST requests with a body
4243
protected override void ProcessMockResponse(ref byte[] body, IList<MockResponseHeader> headers, ProxyRequestArgs e, MockResponse? matchingResponse)
4344
{
4445
base.ProcessMockResponse(ref body, headers, e, matchingResponse);
@@ -47,7 +48,7 @@ protected override void ProcessMockResponse(ref byte[] body, IList<MockResponseH
4748
var changed = false;
4849

4950
StoreLastNonce(e);
50-
UpdateMsalState(ref bodyString, e, ref changed);
51+
UpdateMsalStateInBody(ref bodyString, e, ref changed);
5152
UpdateIdToken(ref bodyString, e, ref changed);
5253
UpdateDevProxyKeyId(ref bodyString, ref changed);
5354
UpdateDevProxyCertificateChain(ref bodyString, ref changed);
@@ -58,6 +59,15 @@ protected override void ProcessMockResponse(ref byte[] body, IList<MockResponseH
5859
}
5960
}
6061

62+
// Running on GET requests without a body
63+
protected override void ProcessMockResponse(ref string? body, IList<MockResponseHeader> headers, ProxyRequestArgs e, MockResponse? matchingResponse)
64+
{
65+
base.ProcessMockResponse(ref body, headers, e, matchingResponse);
66+
67+
StoreLastNonce(e);
68+
UpdateMsalStateInHeaders(headers, e);
69+
}
70+
6171
private void UpdateDevProxyCertificateChain(ref string bodyString, ref bool changed)
6272
{
6373
if (!bodyString.Contains("@dynamic.devProxyCertificateChain"))
@@ -127,7 +137,22 @@ private static string PadBase64(string base64)
127137
return base64 + padding;
128138
}
129139

130-
private void UpdateMsalState(ref string body, ProxyRequestArgs e, ref bool changed)
140+
private static void UpdateMsalStateInHeaders(IList<MockResponseHeader> headers, ProxyRequestArgs e)
141+
{
142+
var locationHeader = headers.FirstOrDefault(h => h.Name.Equals("Location", StringComparison.OrdinalIgnoreCase));
143+
144+
if (locationHeader is null ||
145+
!e.Session.HttpClient.Request.RequestUri.Query.Contains("state="))
146+
{
147+
return;
148+
}
149+
150+
var queryString = HttpUtility.ParseQueryString(e.Session.HttpClient.Request.RequestUri.Query);
151+
var msalState = queryString["state"];
152+
locationHeader.Value = locationHeader.Value.Replace("state=@dynamic", $"state={msalState}");
153+
}
154+
155+
private static void UpdateMsalStateInBody(ref string body, ProxyRequestArgs e, ref bool changed)
131156
{
132157
if (!body.Contains("state=@dynamic") ||
133158
!e.Session.HttpClient.Request.RequestUri.Query.Contains("state="))

0 commit comments

Comments
 (0)