diff --git a/src/client/Microsoft.Identity.Client/Http/HttpManager.cs b/src/client/Microsoft.Identity.Client/Http/HttpManager.cs index f2a0991098..9fd0b66851 100644 --- a/src/client/Microsoft.Identity.Client/Http/HttpManager.cs +++ b/src/client/Microsoft.Identity.Client/Http/HttpManager.cs @@ -136,9 +136,10 @@ public async Task SendRequestAsync( // package 500 errors in a "service not available" exception if ((int)response.StatusCode >= 500 && (int)response.StatusCode < 600) { + string requestUriScrubbed = $"{endpoint.AbsoluteUri.Split('?')[0]}"; throw MsalServiceExceptionFactory.FromHttpResponse( MsalError.ServiceNotAvailable, - "Service is unavailable to process the request", + $"Service is unavailable to process the request. The request Uri is: {requestUriScrubbed} on port {endpoint.Port}", response); } diff --git a/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs b/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs index a7164ec13f..e9212e5446 100644 --- a/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/PublicApiTests/ConfidentialClientApplicationTests.cs @@ -23,6 +23,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using NSubstitute; using Microsoft.Identity.Client.Extensibility; +using System.Net; namespace Microsoft.Identity.Test.Unit.PublicApiTests { @@ -423,6 +424,61 @@ public async Task ConfidentialClientUsingAdfsAsync() } } + [TestMethod] + public async Task ClientCreds_And_AAD_LogRequestUri_OnServerError_Async() + { + using (var httpManager = new MockHttpManager()) + { + var cca = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId) + .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) + .WithClientSecret(TestConstants.ClientSecret) + .WithHttpManager(httpManager) + .WithExtraQueryParameters("parameter=x") + .BuildConcrete(); + var appCacheAccess = cca.AppTokenCache.RecordAccess(); + var userCacheAccess = cca.UserTokenCache.RecordAccess(); + + httpManager.AddInstanceDiscoveryMockHandler(); + httpManager.AddResiliencyMessageMockHandler(HttpMethod.Post, HttpStatusCode.InternalServerError, retryAfter: 0); + + // Acquire Token + var ex = await AssertException.TaskThrowsAsync( + () => cca.AcquireTokenForClient(TestConstants.s_scope.ToArray()).ExecuteAsync()) + .ConfigureAwait(false); + + //Assert + Assert.AreEqual(MsalError.ServiceNotAvailable, ex.ErrorCode); + Assert.IsTrue(ex.Message.Contains(ClientApplicationBase.DefaultAuthority + "oauth2/v2.0/token")); + } + } + + [TestMethod] + public async Task ClientCreds_And_ADFS_LogRequestUri_OnServerError_Async() + { + using (var httpManager = new MockHttpManager()) + { + var cca = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId) + .WithAuthority(new Uri(TestConstants.OnPremiseAuthority), false) + .WithClientSecret(TestConstants.ClientSecret) + .WithHttpManager(httpManager) + .WithExtraQueryParameters("parameter=x") + .BuildConcrete(); + var appCacheAccess = cca.AppTokenCache.RecordAccess(); + var userCacheAccess = cca.UserTokenCache.RecordAccess(); + + httpManager.AddResiliencyMessageMockHandler(HttpMethod.Post, HttpStatusCode.InternalServerError, retryAfter: 0); + + // Acquire Token + var ex = await AssertException.TaskThrowsAsync( + () => cca.AcquireTokenForClient(TestConstants.s_scope.ToArray()).ExecuteAsync()) + .ConfigureAwait(false); + + //Assert + Assert.AreEqual(MsalError.ServiceNotAvailable, ex.ErrorCode); + Assert.IsTrue(ex.Message.Contains(TestConstants.OnPremiseAuthority + "oauth2/token")); + } + } + private enum CredentialType { Certificate,