|
1 | 1 | // Copyright (c) Microsoft. |
2 | 2 | // Licensed under the MIT License. |
3 | 3 |
|
| 4 | +using System; |
4 | 5 | using System.Collections.Generic; |
5 | 6 | using System.Linq; |
6 | 7 | using System.Net.Http; |
@@ -141,6 +142,117 @@ public async Task AcquireTokenForClient_ListAllRequestHeaders_Async() |
141 | 142 | } |
142 | 143 | } |
143 | 144 |
|
| 145 | + [TestMethod] |
| 146 | + public async Task AcquireTokenForClient_WithExtraHttpHeaders_Null_DoesNotChangeHeaders_Async() |
| 147 | + { |
| 148 | + using var httpManager = new MockHttpManager(); |
| 149 | + httpManager.AddInstanceDiscoveryMockHandler(); |
| 150 | + |
| 151 | + HashSet<string> baseline = new(StringComparer.OrdinalIgnoreCase); |
| 152 | + HashSet<string> afterNull = new(StringComparer.OrdinalIgnoreCase); |
| 153 | + |
| 154 | + httpManager.AddMockHandler(new MockHttpMessageHandler |
| 155 | + { |
| 156 | + ExpectedMethod = HttpMethod.Post, |
| 157 | + ResponseMessage = MockHelpers.CreateSuccessfulClientCredentialTokenResponseMessage(), |
| 158 | + AdditionalRequestValidation = req => { foreach (var h in EnumerateAllHeaders(req)) baseline.Add(h.Key); } |
| 159 | + }); |
| 160 | + |
| 161 | + var app1 = ConfidentialClientApplicationBuilder.Create(_clientId) |
| 162 | + .WithAuthority("https://login.microsoftonline.com/", _tenantId) |
| 163 | + .WithClientSecret("ClientSecret") |
| 164 | + .WithHttpManager(httpManager) |
| 165 | + .BuildConcrete(); |
| 166 | + |
| 167 | + await app1.AcquireTokenForClient(new[] { _scope }).ExecuteAsync().ConfigureAwait(false); |
| 168 | + |
| 169 | + httpManager.AddMockHandler(new MockHttpMessageHandler |
| 170 | + { |
| 171 | + ExpectedMethod = HttpMethod.Post, |
| 172 | + ResponseMessage = MockHelpers.CreateSuccessfulClientCredentialTokenResponseMessage(), |
| 173 | + AdditionalRequestValidation = req => { foreach (var h in EnumerateAllHeaders(req)) afterNull.Add(h.Key); } |
| 174 | + }); |
| 175 | + |
| 176 | + var app2 = ConfidentialClientApplicationBuilder.Create(_clientId) |
| 177 | + .WithAuthority("https://login.microsoftonline.com/", _tenantId) |
| 178 | + .WithClientSecret("ClientSecret") |
| 179 | + .WithHttpManager(httpManager) |
| 180 | + .BuildConcrete(); |
| 181 | + |
| 182 | + Dictionary<string, string> headers = null; |
| 183 | + await app2.AcquireTokenForClient(new[] { _scope }) |
| 184 | + .WithExtraHttpHeaders(headers) |
| 185 | + .ExecuteAsync().ConfigureAwait(false); |
| 186 | + |
| 187 | + CollectionAssert.AreEquivalent(baseline.ToList(), afterNull.ToList(), |
| 188 | + "Null headers should not change the header set."); |
| 189 | + } |
| 190 | + |
| 191 | + [TestMethod] |
| 192 | + public async Task AcquireTokenForClient_ExtraHeaders_OverridesDefault_Async() |
| 193 | + { |
| 194 | + using var httpManager = new MockHttpManager(); |
| 195 | + httpManager.AddInstanceDiscoveryMockHandler(); |
| 196 | + httpManager.AddMockHandler(new MockHttpMessageHandler |
| 197 | + { |
| 198 | + ExpectedMethod = HttpMethod.Post, |
| 199 | + ResponseMessage = MockHelpers.CreateSuccessfulClientCredentialTokenResponseMessage(), |
| 200 | + AdditionalRequestValidation = (HttpRequestMessage req) => |
| 201 | + { |
| 202 | + Assert.IsTrue(TryGetHeader(req, "Accept", out var v), "Accept not present"); |
| 203 | + Assert.AreEqual("text/plain", v); // user value should win |
| 204 | + } |
| 205 | + }); |
| 206 | + |
| 207 | + var app = ConfidentialClientApplicationBuilder.Create(_clientId) |
| 208 | + .WithAuthority("https://login.microsoftonline.com/", _tenantId) |
| 209 | + .WithClientSecret("ClientSecret") |
| 210 | + .WithHttpManager(httpManager) |
| 211 | + .BuildConcrete(); |
| 212 | + |
| 213 | + var headers = new Dictionary<string, string> { ["Accept"] = "text/plain" }; |
| 214 | + var result = await app.AcquireTokenForClient(new[] { _scope }) |
| 215 | + .WithExtraHttpHeaders(headers) |
| 216 | + .ExecuteAsync().ConfigureAwait(false); |
| 217 | + |
| 218 | + Assert.IsNotNull(result); |
| 219 | + } |
| 220 | + |
| 221 | + [TestMethod] |
| 222 | + public async Task AcquireTokenForClient_MultipleWithExtraHttpHeaders_Calls_LastWins_Async() |
| 223 | + { |
| 224 | + using var httpManager = new MockHttpManager(); |
| 225 | + httpManager.AddInstanceDiscoveryMockHandler(); |
| 226 | + |
| 227 | + httpManager.AddMockHandler(new MockHttpMessageHandler |
| 228 | + { |
| 229 | + ExpectedMethod = HttpMethod.Post, |
| 230 | + ResponseMessage = MockHelpers.CreateSuccessfulClientCredentialTokenResponseMessage(), |
| 231 | + AdditionalRequestValidation = (HttpRequestMessage req) => |
| 232 | + { |
| 233 | + // Only the last set of headers should be present |
| 234 | + Assert.IsTrue(TryGetHeader(req, "x-ms-test", out var v1), "x-ms-test not present."); |
| 235 | + Assert.AreEqual("final", v1); |
| 236 | + Assert.IsFalse(TryGetHeader(req, "x-ms-old", out _), "x-ms-old should not be present."); |
| 237 | + } |
| 238 | + }); |
| 239 | + |
| 240 | + var app = ConfidentialClientApplicationBuilder |
| 241 | + .Create(_clientId) |
| 242 | + .WithAuthority("https://login.microsoftonline.com/", _tenantId) |
| 243 | + .WithClientSecret("ClientSecret") |
| 244 | + .WithHttpManager(httpManager) |
| 245 | + .BuildConcrete(); |
| 246 | + |
| 247 | + var result = await app.AcquireTokenForClient(new[] { _scope }) |
| 248 | + .WithExtraHttpHeaders(new Dictionary<string, string> { ["x-ms-test"] = "initial", ["x-ms-old"] = "old" }) |
| 249 | + .WithExtraHttpHeaders(new Dictionary<string, string> { ["x-ms-test"] = "final" }) // last call should win |
| 250 | + .ExecuteAsync() |
| 251 | + .ConfigureAwait(false); |
| 252 | + |
| 253 | + Assert.IsNotNull(result); |
| 254 | + } |
| 255 | + |
144 | 256 | private static IEnumerable<KeyValuePair<string, IEnumerable<string>>> EnumerateAllHeaders(HttpRequestMessage req) |
145 | 257 | { |
146 | 258 | foreach (var h in req.Headers) |
|
0 commit comments