Skip to content

Commit

Permalink
Merge branch 'master' into kecaruso/dont-mutate-options
Browse files Browse the repository at this point in the history
  • Loading branch information
jennyf19 authored Dec 3, 2024
2 parents 273581a + 99dd5a4 commit 16bb2e1
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 5 deletions.
2 changes: 1 addition & 1 deletion build/template-install-dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ steps:
- task: UseDotNet@2
displayName: 'Use .NET SDK 9.0.x'
inputs:
version: 9.0.x
useGlobalJson: true

# Run Nuget Tool Installer

Expand Down
9 changes: 9 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"msbuild-sdks": {
"Microsoft.Build.NoTargets": "3.7.56"
},
"sdk": {
"version": "9.0.0",
"rollForward": "latestFeature"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public static IServiceCollection AddTokenAcquisition(
ServiceDescriptor? tokenAcquisitionhost = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquisitionHost));
ServiceDescriptor? authenticationHeaderCreator = services.FirstOrDefault(s => s.ServiceType == typeof(IAuthorizationHeaderProvider));
ServiceDescriptor? tokenAcquirerFactory = services.FirstOrDefault(s => s.ServiceType == typeof(ITokenAcquirerFactory));
if (tokenAcquisitionService != null && tokenAcquisitionInternalService != null && tokenAcquisitionhost != null && authenticationHeaderCreator != null && tokenAcquirerFactory != null)
if (tokenAcquisitionService != null && tokenAcquisitionInternalService != null && tokenAcquisitionhost != null && authenticationHeaderCreator != null)
{
if (isTokenAcquisitionSingleton ^ (tokenAcquisitionService.Lifetime == ServiceLifetime.Singleton))
{
Expand All @@ -77,8 +77,13 @@ public static IServiceCollection AddTokenAcquisition(
services.Remove(tokenAcquisitionInternalService);
services.Remove(tokenAcquisitionhost);
services.Remove(authenticationHeaderCreator);
services.Remove(tokenAcquirerFactory);
tokenAcquirerFactory = null;

// To support ASP.NET Core 2.x on .NET FW. It won't use the TokenAcquirerFactory.GetDefaultInstance()
if (tokenAcquirerFactory != null)
{
services.Remove(tokenAcquirerFactory);
tokenAcquirerFactory = null;
}
}
else
{
Expand Down
106 changes: 105 additions & 1 deletion tests/Microsoft.Identity.Web.Test/ServiceCollectionExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Abstractions;
Expand Down Expand Up @@ -140,6 +139,111 @@ public void AddHttpContextAccessor_ThrowsWithoutServices()
{
Assert.Throws<ArgumentNullException>("services", () => ServiceCollectionExtensions.AddTokenAcquisition(null!));
}

[Fact]
public void AddTokenAcquisitionCalledTwice_RegistersTokenAcquisitionOnlyAsSingleton_WhenFlagIsTrue()
{
// Arrange
var services = new ServiceCollection();

// Act
// Token acquisition services were originally registered as scoped
services.AddTokenAcquisition();

// Token acquisition services should now be registered as singleton
services.AddTokenAcquisition(isTokenAcquisitionSingleton: true);

// Assert
var orderedServices = services.OrderBy(s => s.ServiceType.FullName).ToList();

// Check that the first service is registered as singleton
Assert.Collection(
orderedServices,
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(IPostConfigureOptions<MicrosoftIdentityApplicationOptions>), actual.ServiceType);
Assert.Equal(typeof(MicrosoftIdentityApplicationOptionsMerger), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
}, actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(IPostConfigureOptions<ConfidentialClientApplicationOptions>), actual.ServiceType);
Assert.Equal(typeof(ConfidentialClientApplicationOptionsMerger), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(IPostConfigureOptions<MicrosoftIdentityOptions>), actual.ServiceType);
Assert.Equal(typeof(MicrosoftIdentityOptionsMerger), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(IAuthorizationHeaderProvider), actual.ServiceType);
Assert.Equal(typeof(DefaultAuthorizationHeaderProvider), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(typeof(ICredentialsLoader), actual.ServiceType);
Assert.Equal(typeof(DefaultCertificateLoader), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(ITokenAcquirerFactory), actual.ServiceType);
Assert.Equal(typeof(DefaultTokenAcquirerFactoryImplementation), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(IMergedOptionsStore), actual.ServiceType);
Assert.Equal(typeof(MergedOptionsStore), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(IMergedOptionsStore), actual.ServiceType);
Assert.Equal(typeof(MergedOptionsStore), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(ITokenAcquisition), actual.ServiceType);
Assert.Equal(typeof(TokenAcquisitionAspNetCore), actual.ImplementationType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(ITokenAcquisitionHost), actual.ServiceType);
Assert.Null(actual.ImplementationInstance);
Assert.Null(actual.ImplementationFactory);
},
actual =>
{
Assert.Equal(ServiceLifetime.Singleton, actual.Lifetime);
Assert.Equal(typeof(ITokenAcquisitionInternal), actual.ServiceType);
Assert.Null(actual.ImplementationInstance);
Assert.NotNull(actual.ImplementationFactory);
});
}
}

internal class MockCredentialsLoader : ICredentialsLoader
Expand Down

0 comments on commit 16bb2e1

Please sign in to comment.