Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -23,16 +24,27 @@ public static class DownstreamApiExtensions
/// This is the name used when calling the service from controller/pages.</param>
/// <param name="configuration">Configuration.</param>
/// <returns>The builder for chaining.</returns>
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static IServiceCollection AddDownstreamApi(
this IServiceCollection services,
string serviceName,
IConfiguration configuration)
{
_ = Throws.IfNull(services);

#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
// Help the compiler figure out the type so that the code generator generates the binding code
services.AddOptions<DownstreamApiOptions>(serviceName)
.Bind(configuration);
#else
// Help the compiler figure out the type so that the code generator generates
// the binding code
services.Configure<DownstreamApiOptions>(serviceName, configuration);
#endif
RegisterDownstreamApi(services);
return services;
}
Expand Down Expand Up @@ -65,6 +77,10 @@ public static IServiceCollection AddDownstreamApi(
/// This is the name used when calling the service from controller/pages.</param>
/// <param name="configurationSection">Configuration section.</param>
/// <returns>The builder for chaining.</returns>
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static IServiceCollection AddDownstreamApis(
this IServiceCollection services,
IConfigurationSection configurationSection)
Expand All @@ -78,7 +94,13 @@ public static IServiceCollection AddDownstreamApis(

foreach (var optionsForService in options.Keys)
{
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
services.AddOptions<DownstreamApiOptions>(optionsForService)
.Bind(configurationSection.GetSection(optionsForService));
#else
services.Configure<DownstreamApiOptions>(optionsForService, configurationSection.GetSection(optionsForService));
#endif
}
RegisterDownstreamApi(services);
return services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -40,9 +41,20 @@ public static IServiceCollection AddMicrosoftGraph(this IServiceCollection servi
/// <param name="services">Builder.</param>
/// <param name="configurationSection">Configuration section containing the Microsoft graph config.</param>
/// <returns>The service collection to chain.</returns>
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static IServiceCollection AddMicrosoftGraph(this IServiceCollection services, IConfiguration configurationSection)
{
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
services.AddOptions<GraphServiceClientOptions>()
.Bind(configurationSection);
return services.AddMicrosoftGraph(_ => { }); // No-op, binding already done
#else
return services.AddMicrosoftGraph(o => configurationSection.Bind(o));
#endif
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -40,9 +41,20 @@ public static IServiceCollection AddMicrosoftGraphBeta(this IServiceCollection s
/// <param name="services">Builder.</param>
/// <param name="configurationSection">Configuration section containing the Microsoft graph config.</param>
/// <returns>The service collection to chain.</returns>
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static IServiceCollection AddMicrosoftGraphBeta(this IServiceCollection services, IConfiguration configurationSection)
{
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
services.AddOptions<GraphServiceClientOptions>()
.Bind(configurationSection);
return services.AddMicrosoftGraphBeta(_ => { }); // No-op, binding already done
#else
return services.AddMicrosoftGraphBeta(o => configurationSection.Bind(o));
#endif
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,24 @@ public static class MicrosoftGraphExtensions
/// <returns>The builder to chain.</returns>
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
[RequiresUnreferencedCode("Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object).")]
#endif
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static MicrosoftIdentityAppCallsWebApiAuthenticationBuilder AddMicrosoftGraph(
this MicrosoftIdentityAppCallsWebApiAuthenticationBuilder builder,
IConfigurationSection configurationSection)
{
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
builder.Services.AddOptions<MicrosoftGraphOptions>()
.Bind(configurationSection);
return builder.AddMicrosoftGraph(_ => { }); // No-op, binding already done
#else
return builder.AddMicrosoftGraph(
options => configurationSection.Bind(options));
#endif
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public class MicrosoftIdentityBaseAuthenticationBuilder
/// <param name="configurationSection">Optional configuration section.</param>
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
[RequiresUnreferencedCode("Calls Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object).")]
#endif
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "LoggingOptions is a simple POCO compatible with source generators")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "LoggingOptions is a simple POCO compatible with source generators")]
#endif
protected MicrosoftIdentityBaseAuthenticationBuilder(
IServiceCollection services,
Expand All @@ -38,6 +42,9 @@ protected MicrosoftIdentityBaseAuthenticationBuilder(
IdentityModelEventSource.ShowPII = logOptions.EnablePiiLogging;
}

#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "GetValue<string> for primitive types is AOT-safe")]
#endif
internal static void SetIdentityModelLogger(IServiceProvider serviceProvider)
{
if (serviceProvider != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ protected TokenAcquirerFactory()
/// </example>
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
[RequiresUnreferencedCode("Calls Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object).")]
#endif
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
static public T GetDefaultInstance<T>(string configSection="AzureAd") where T : TokenAcquirerFactory, new()
{
Expand All @@ -95,13 +99,25 @@ protected TokenAcquirerFactory()
defaultInstance = instance;
instance.Services.AddTokenAcquisition();
instance.Services.AddHttpClient();
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
var configSection2 = instance.Configuration.GetSection(configSection);
instance.Services.AddOptions<MicrosoftIdentityApplicationOptions>()
.Bind(configSection2);
instance.Services.Configure<MicrosoftIdentityApplicationOptions>(option =>
{
// This is temporary and will be removed eventually.
CiamAuthorityHelper.BuildCiamAuthorityIfNeeded(option);
});
#else
instance.Services.Configure<MicrosoftIdentityApplicationOptions>(option =>
{
instance.Configuration.GetSection(configSection).Bind(option);

// This is temporary and will be removed eventually.
CiamAuthorityHelper.BuildCiamAuthorityIfNeeded(option);
});
#endif
instance.Services.AddSingleton<ITokenAcquirerFactory, DefaultTokenAcquirerFactoryImplementation>();
instance.Services.AddSingleton(defaultInstance.Configuration);
}
Expand All @@ -123,6 +139,10 @@ protected TokenAcquirerFactory()
/// </example>
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
[RequiresUnreferencedCode("Calls Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object).")]
#endif
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
static public TokenAcquirerFactory GetDefaultInstance(string configSection = "AzureAd")
{
Expand All @@ -138,13 +158,25 @@ static public TokenAcquirerFactory GetDefaultInstance(string configSection = "Az
defaultInstance = instance;
instance.Services.AddTokenAcquisition();
instance.Services.AddHttpClient();
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
var configSection2 = instance.Configuration.GetSection(configSection);
instance.Services.AddOptions<MicrosoftIdentityApplicationOptions>()
.Bind(configSection2);
instance.Services.Configure<MicrosoftIdentityApplicationOptions>(option =>
{
// This is temporary and will be removed eventually.
CiamAuthorityHelper.BuildCiamAuthorityIfNeeded(option);
});
#else
instance.Services.Configure<MicrosoftIdentityApplicationOptions>(option =>
{
instance.Configuration.GetSection(configSection).Bind(option);

// This is temporary and will be removed eventually.
CiamAuthorityHelper.BuildCiamAuthorityIfNeeded(option);
});
#endif
instance.Services.AddSingleton<ITokenAcquirerFactory, DefaultTokenAcquirerFactoryImplementation>();
instance.Services.AddSingleton(defaultInstance.Configuration);
}
Expand Down
12 changes: 12 additions & 0 deletions src/Microsoft.Identity.Web.TokenAcquisition/WebApiBuilders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public static class WebApiBuilders
/// <returns>The authentication builder to chain.</returns>
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
[RequiresUnreferencedCode("Calls Bind, Configure with Unspecified Configuration and ServiceCollection.")]
#endif
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static MicrosoftIdentityAppCallsWebApiAuthenticationBuilder EnableTokenAcquisition(
Action<ConfidentialClientApplicationOptions> configureConfidentialClientApplicationOptions,
Expand All @@ -37,6 +41,13 @@ public static MicrosoftIdentityAppCallsWebApiAuthenticationBuilder EnableTokenAc
{
if (configuration != null)
{
#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
services.AddOptions<MicrosoftIdentityApplicationOptions>(authenticationScheme)
.Bind(configuration);
services.AddOptions<MicrosoftIdentityOptions>(authenticationScheme)
.Bind(configuration);
#else
// TODO: This never was right. And the configureConfidentialClientApplicationOptions delegate is not used
// services.Configure<ConfidentialClientApplicationOptions>(authenticationScheme, configuration);
services.Configure<MicrosoftIdentityApplicationOptions>(authenticationScheme, options
Expand All @@ -45,6 +56,7 @@ public static MicrosoftIdentityAppCallsWebApiAuthenticationBuilder EnableTokenAc
services.Configure<MicrosoftIdentityOptions>(authenticationScheme, options
=>
{ configuration.Bind(options); });
#endif
}
services.AddTokenAcquisition();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public static class DownstreamWebApiExtensions
[EditorBrowsable(EditorBrowsableState.Never)]
#if NET6_0_OR_GREATER && !NET8_0_OR_GREATER
[RequiresUnreferencedCode("Calls Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure<TOutput>(IServiceCollection, String, IConfiguration).")]
#endif
#if NET8_0_OR_GREATER
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
[UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.", Justification = "Configuration binding with AddOptions<T>().Bind() uses source generators on .NET 8+")]
#endif
public static MicrosoftIdentityAppCallsWebApiAuthenticationBuilder AddDownstreamWebApi(
this MicrosoftIdentityAppCallsWebApiAuthenticationBuilder builder,
Expand All @@ -35,7 +39,13 @@ public static MicrosoftIdentityAppCallsWebApiAuthenticationBuilder AddDownstream
{
_ = Throws.IfNull(builder);

#if NET8_0_OR_GREATER
// For .NET 8+, use source generator-based binding for AOT compatibility
builder.Services.AddOptions<DownstreamWebApiOptions>(serviceName)
.Bind(configuration);
#else
builder.Services.Configure<DownstreamWebApiOptions>(serviceName, configuration);
#endif
builder.Services.AddHttpClient<IDownstreamWebApi, DownstreamWebApi>();
return builder;
}
Expand Down
Loading
Loading