Skip to content

Trim and AOT-incompatible APIs with .NET 9 #3576

@anuchandy

Description

@anuchandy

Microsoft.Identity.Web Library

Microsoft.Identity.Web

Microsoft.Identity.Web version

4.0.0

Web app

Sign-in users and call web APIs

Web API

Protected web APIs call downstream web APIs

Token cache serialization

In-memory caches

Description

While trying to use Microsoft.Identity.Web (4.0.0) with an AOT-compatible application (Azure MCP Server), we encountered trimmer errors summarized in the below table.

Component Method Issue Root Cause
MicrosoftIdentityWebApiAuthenticationBuilderExtensions <AddMicrosoftIdentityWebApi>b__0(JwtBearerOptions) IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
MicrosoftIdentityWebApiAuthenticationBuilderExtensions <AddMicrosoftIdentityWebApi>b__1(JwtBearerOptions) IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
MicrosoftIdentityWebApiAuthenticationBuilderExtensions <AddMicrosoftIdentityWebApi>b__2(MicrosoftIdentityOptions) IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
MicrosoftIdentityWebApiAuthenticationBuilder EnableTokenAcquisitionToCallDownstreamApi() IL2026 Constructor chain requires unreferenced code
MicrosoftIdentityWebApiAuthenticationBuilderWithConfiguration <EnableTokenAcquisitionToCallDownstreamApi>b__1_0(ConfidentialClientApplicationOptions) IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
ScopeOrAppPermissionAuthorizationHandler HandleRequirementAsync() IL2026 ConfigurationBinder.GetValue<T>() requires unreferenced code
WebApiBuilders <EnableTokenAcquisition>b__0(MicrosoftIdentityApplicationOptions) IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
WebApiBuilders <EnableTokenAcquisition>b__1(MicrosoftIdentityOptions) IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
MicrosoftIdentityBaseAuthenticationBuilder Constructor IL2026 ConfigurationBinder.Bind(IConfiguration, Object) requires unreferenced code
MicrosoftIdentityBaseAuthenticationBuilder SetIdentityModelLogger() IL2026 ConfigurationBinder.GetValue<T>() requires unreferenced code
WebApiBuilders EnableTokenAcquisition() IL2026 Constructor chain requires unreferenced code

Affected Methods:

  • MicrosoftIdentityWebApiAuthenticationBuilder.EnableTokenAcquisitionToCallDownstreamApi()
  • WebApiBuilders.EnableTokenAcquisition()

Reproduction steps

repro-aot-identity-web.zip

Please use attached repro code and build it with

dotnet publish -c Release --self-contained -p:PublishTrimmed=true -p:PublishSingleFile=true --runtime osx-arm64

Error message

The build will report the following trimmer errors

  IdentityWebAotRepro failed with 12 error(s) (28.7s) → bin/Release/net9.0/osx-arm64/IdentityWebAotRepro.dll
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass1_0.<AddMicrosoftIdentityWebApi>b__0(JwtBearerOptions): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass1_0.<AddMicrosoftIdentityWebApi>b__1(JwtBearerOptions): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass1_0.<AddMicrosoftIdentityWebApi>b__2(MicrosoftIdentityOptions): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilder.EnableTokenAcquisitionToCallDownstreamApi(Action<ConfidentialClientApplicationOptions>): Using member 'Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder(IServiceCollection, IConfigurationSection)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Calls Microsoft.Identity.Web.MicrosoftIdentityBaseAuthenticationBuilder.MicrosoftIdentityBaseAuthenticationBuilder(IServiceCollection, IConfigurationSection).
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderWithConfiguration.<EnableTokenAcquisitionToCallDownstreamApi>b__1_0(ConfidentialClientApplicationOptions): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.ScopeOrAppPermissionAuthorizationHandler.HandleRequirementAsync(AuthorizationHandlerContext, ScopeOrAppPermissionAuthorizationRequirement): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue<T>(IConfiguration, String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.Internal.WebApiBuilders.<>c__DisplayClass0_0.<EnableTokenAcquisition>b__0(MicrosoftIdentityApplicationOptions): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.Internal.WebApiBuilders.<>c__DisplayClass0_0.<EnableTokenAcquisition>b__1(MicrosoftIdentityOptions): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityBaseAuthenticationBuilder.MicrosoftIdentityBaseAuthenticationBuilder(IServiceCollection, IConfigurationSection): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.MicrosoftIdentityBaseAuthenticationBuilder.SetIdentityModelLogger(IServiceProvider): Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.GetValue<T>(IConfiguration, String)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. In case the type is non-primitive, the trimmer cannot statically analyze the object's type so its members may be trimmed.
    ILLink : Trim analysis error IL2026: Microsoft.Identity.Web.Internal.WebApiBuilders.EnableTokenAcquisition(Action<ConfidentialClientApplicationOptions>, String, IServiceCollection, IConfigurationSection): Using member 'Microsoft.Identity.Web.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder.MicrosoftIdentityAppCallsWebApiAuthenticationBuilder(IServiceCollection, IConfigurationSection)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Calls Microsoft.Identity.Web.MicrosoftIdentityBaseAuthenticationBuilder.MicrosoftIdentityBaseAuthenticationBuilder(IServiceCollection, IConfigurationSection).
    /Users/anuchandy/.nuget/packages/microsoft.net.illink.tasks/9.0.7/build/Microsoft.NET.ILLink.targets(96,5): error NETSDK1144: Optimizing assemblies for size failed.

Build failed with 12 error(s) in 34.5s

Id Web logs

No response

Relevant code snippets

Please use the ready-to-run attached project — it essentially uses the same following code.

### program.cs

#
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Configure forwarded headers for reverse proxy scenarios
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    options.KnownNetworks.Clear();
    options.KnownProxies.Clear();
});

// Add HTTP context accessor
builder.Services.AddHttpContextAccessor();

// Create Azure AD configuration similar to real-world scenarios
var azureAdConfig = CreateAzureAdConfiguration();

// This is where AOT violations likely occur
builder.Services.AddMicrosoftIdentityWebApiAuthentication(azureAdConfig, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

var app = builder.Build();

// Configure middleware pipeline
app.UseForwardedHeaders();
app.UseAuthentication();
app.UseAuthorization();

// Simple endpoint that requires authentication
app.MapGet("/api/health", () => "OK")
   .RequireAuthorization();

app.Run();

static IConfiguration CreateAzureAdConfiguration()
{
    // Sample configuration that mimics real Azure AD settings
    var configData = new Dictionary<string, string?>
    {
        ["AzureAd:Instance"] = "https://login.microsoftonline.com/",
        ["AzureAd:TenantId"] = "12345678-1234-1234-1234-123456789012",
        ["AzureAd:ClientId"] = "87654321-4321-4321-4321-210987654321", 
        ["AzureAd:Audience"] = "api://my-api",
        ["AzureAd:ClientSecret"] = "fake-client-secret-for-testing"
    };

    return new ConfigurationBuilder()
        .AddInMemoryCollection(configData)
        .Build();
}



### csproj


<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <IsAotCompatible>true</IsAotCompatible>
    <PublishSingleFile>false</PublishSingleFile>
    <SelfContained>false</SelfContained>
    <PublishTrimmed>false</PublishTrimmed>
  </PropertyGroup>

  <!-- Enable Trim and AOT Analyzers -->
  <PropertyGroup>
    <EnableAotAnalyzer>true</EnableAotAnalyzer>
    <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
    <EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
    <TrimmerSingleWarn>false</TrimmerSingleWarn>
    <SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
  </PropertyGroup>

  <ItemGroup>
    <!-- Microsoft Identity Web package that causes AOT violations -->
    <PackageReference Include="Microsoft.Identity.Web" Version="4.0.0" />
  </ItemGroup>

</Project>

Regression

No response

Expected behavior

The library should be AOT-clean. Based on our internal discussion, this appears to be a flow that wasn’t caught by the existing gates.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions