|
4 | 4 | using System; |
5 | 5 | using System.Collections.Generic; |
6 | 6 | using System.Net.Http; |
| 7 | +using System.Security.Claims; |
7 | 8 | using System.Threading; |
8 | 9 | using System.Threading.Tasks; |
9 | 10 | using Microsoft.Extensions.DependencyInjection; |
| 11 | +using Microsoft.Extensions.Logging; |
10 | 12 | using Microsoft.Identity.Abstractions; |
11 | 13 | using Microsoft.Identity.Client; |
12 | 14 | using Microsoft.Identity.Web.Extensibility; |
13 | 15 | using Microsoft.Identity.Web.Test.Common; |
14 | 16 | using Microsoft.Identity.Web.Test.Common.Mocks; |
15 | 17 | using Microsoft.Identity.Web.TestOnly; |
| 18 | +using NSubstitute; |
16 | 19 | using Xunit; |
17 | 20 |
|
18 | 21 |
|
@@ -160,6 +163,44 @@ public async Task ExtraBodyParametersAreSentToEndpointTest() |
160 | 163 | Assert.Equal("Bearer header.payload.signature", result); |
161 | 164 | } |
162 | 165 |
|
| 166 | + /// <summary> |
| 167 | + /// Tests that a caught <see cref="MsalUiRequiredException"/> is not re-logged by Microsoft.Identity.Web, |
| 168 | + /// since MSAL.NET already logs it. Re-logging produced duplicate log entries. |
| 169 | + /// This addresses issue #3528. |
| 170 | + /// </summary> |
| 171 | + [Fact] |
| 172 | + public async Task GetAuthenticationResultForUserAsync_DoesNotDuplicateLog_WhenMsalUiRequiredExceptionIsThrown() |
| 173 | + { |
| 174 | + // Arrange |
| 175 | + var tokenAcquirerFactory = InitTokenAcquirerFactory(); |
| 176 | + |
| 177 | + var innerLogger = Substitute.For<ILogger<TokenAcquisition>>(); |
| 178 | + innerLogger.IsEnabled(Arg.Any<Microsoft.Extensions.Logging.LogLevel>()).Returns(true); |
| 179 | + tokenAcquirerFactory.Services.AddSingleton<ILogger<TokenAcquisition>>( |
| 180 | + new LoggerMock<TokenAcquisition>(innerLogger)); |
| 181 | + |
| 182 | + IServiceProvider serviceProvider = tokenAcquirerFactory.Build(); |
| 183 | + IAuthorizationHeaderProvider authorizationHeaderProvider = serviceProvider.GetRequiredService<IAuthorizationHeaderProvider>(); |
| 184 | + |
| 185 | + // No account/login-hint claims, so MSAL's AcquireTokenSilent throws MsalUiRequiredException |
| 186 | + // synchronously (the exact scenario reported in issue #3528). |
| 187 | + var user = new ClaimsPrincipal(new Microsoft.IdentityModel.Tokens.CaseSensitiveClaimsIdentity()); |
| 188 | + |
| 189 | + // Act & Assert |
| 190 | + await Assert.ThrowsAsync<MicrosoftIdentityWebChallengeUserException>(() => |
| 191 | + authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync( |
| 192 | + new[] { "https://graph.microsoft.com/.default" }, |
| 193 | + authorizationHeaderProviderOptions: null, |
| 194 | + claimsPrincipal: user)); |
| 195 | + |
| 196 | + innerLogger.DidNotReceive().Log( |
| 197 | + Microsoft.Extensions.Logging.LogLevel.Information, |
| 198 | + Arg.Is<EventId>(e => e.Id == 300), // LoggingEventId.TokenAcquisitionError |
| 199 | + Arg.Any<object>(), |
| 200 | + Arg.Any<Exception?>(), |
| 201 | + Arg.Any<Func<object, Exception?, string>>()); |
| 202 | + } |
| 203 | + |
163 | 204 | private TokenAcquirerFactory InitTokenAcquirerFactory() |
164 | 205 | { |
165 | 206 | TokenAcquirerFactoryTesting.ResetTokenAcquirerFactoryInTest(); |
|
0 commit comments