Skip to content

Commit 4cbb58a

Browse files
Copilotpmaytak
andauthored
Fix GetTokenAcquirer to propagate MicrosoftEntraApplicationOptions properties (#3651)
* Initial plan * Fix GetTokenAcquirer to propagate MicrosoftEntraApplicationOptions properties Co-authored-by: pmaytak <[email protected]> * Rename variables to camelCase and copy Authority property from MicrosoftEntraApplicationOptions Co-authored-by: pmaytak <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: pmaytak <[email protected]>
1 parent d050622 commit 4cbb58a

File tree

2 files changed

+185
-5
lines changed

2 files changed

+185
-5
lines changed

src/Microsoft.Identity.Web.TokenAcquisition/DefaultTokenAcquirerFactoryImplementation.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ public ITokenAcquirer GetTokenAcquirer(IdentityApplicationOptions IdentityApplic
5959
_ = Throws.IfNull(IdentityApplicationOptions);
6060

6161
// Compute the Azure region if the option is a MicrosoftIdentityApplicationOptions.
62-
MicrosoftIdentityApplicationOptions? MicrosoftIdentityApplicationOptions = IdentityApplicationOptions as MicrosoftIdentityApplicationOptions;
63-
if (MicrosoftIdentityApplicationOptions == null)
62+
MicrosoftIdentityApplicationOptions? microsoftIdentityApplicationOptions = IdentityApplicationOptions as MicrosoftIdentityApplicationOptions;
63+
if (microsoftIdentityApplicationOptions == null)
6464
{
65-
MicrosoftIdentityApplicationOptions = new MicrosoftIdentityApplicationOptions
65+
microsoftIdentityApplicationOptions = new MicrosoftIdentityApplicationOptions
6666
{
6767
AllowWebApiToBeAuthorizedByACL = IdentityApplicationOptions.AllowWebApiToBeAuthorizedByACL,
6868
Audience = IdentityApplicationOptions.Audience,
@@ -73,17 +73,32 @@ public ITokenAcquirer GetTokenAcquirer(IdentityApplicationOptions IdentityApplic
7373
TokenDecryptionCredentials = IdentityApplicationOptions.TokenDecryptionCredentials,
7474
EnablePiiLogging = IdentityApplicationOptions.EnablePiiLogging,
7575
};
76+
77+
// If the IdentityApplicationOptions is of type MicrosoftEntraApplicationOptions,
78+
// copy over those options too.
79+
MicrosoftEntraApplicationOptions? microsoftEntraApplicationOptions = IdentityApplicationOptions as MicrosoftEntraApplicationOptions;
80+
if (microsoftEntraApplicationOptions != null)
81+
{
82+
microsoftIdentityApplicationOptions.Authority = microsoftEntraApplicationOptions.Authority;
83+
microsoftIdentityApplicationOptions.Name = microsoftEntraApplicationOptions.Name;
84+
microsoftIdentityApplicationOptions.Instance = microsoftEntraApplicationOptions.Instance;
85+
microsoftIdentityApplicationOptions.TenantId = microsoftEntraApplicationOptions.TenantId;
86+
microsoftIdentityApplicationOptions.AppHomeTenantId = microsoftEntraApplicationOptions.AppHomeTenantId;
87+
microsoftIdentityApplicationOptions.AzureRegion = microsoftEntraApplicationOptions.AzureRegion;
88+
microsoftIdentityApplicationOptions.ClientCapabilities = microsoftEntraApplicationOptions.ClientCapabilities;
89+
microsoftIdentityApplicationOptions.SendX5C = microsoftEntraApplicationOptions.SendX5C;
90+
}
7691
}
7792

78-
string key = GetKey(IdentityApplicationOptions.Authority, IdentityApplicationOptions.ClientId, MicrosoftIdentityApplicationOptions.AzureRegion);
93+
string key = GetKey(IdentityApplicationOptions.Authority, IdentityApplicationOptions.ClientId, microsoftIdentityApplicationOptions.AzureRegion);
7994

8095
return _authSchemes.GetOrAdd(key, (key) =>
8196
{
8297
IMergedOptionsStore optionsMonitor = ServiceProvider!.GetRequiredService<IMergedOptionsStore>();
8398
MergedOptions mergedOptions = optionsMonitor.Get(key);
8499

85100

86-
MergedOptions.UpdateMergedOptionsFromMicrosoftIdentityApplicationOptions(MicrosoftIdentityApplicationOptions, mergedOptions);
101+
MergedOptions.UpdateMergedOptionsFromMicrosoftIdentityApplicationOptions(microsoftIdentityApplicationOptions, mergedOptions);
87102
return MakeTokenAcquirer(key);
88103
});
89104
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using Microsoft.Identity.Abstractions;
9+
using Microsoft.Identity.Web.Test.Common;
10+
using Xunit;
11+
12+
namespace Microsoft.Identity.Web.Test
13+
{
14+
[Collection(nameof(TokenAcquirerFactorySingletonProtection))]
15+
public class DefaultTokenAcquirerFactoryImplementationTests
16+
{
17+
[Fact]
18+
public void GetTokenAcquirer_WithMicrosoftEntraApplicationOptions_PropagatesAllOptions()
19+
{
20+
// Arrange
21+
var taf = new CustomTAF();
22+
var provider = taf.Build();
23+
var factory = provider.GetRequiredService<ITokenAcquirerFactory>();
24+
25+
var options = new MicrosoftEntraApplicationOptions
26+
{
27+
// IdentityApplicationOptions properties
28+
ClientId = "test-client-id",
29+
Authority = "https://login.microsoftonline.com/test-tenant",
30+
EnablePiiLogging = true,
31+
AllowWebApiToBeAuthorizedByACL = true,
32+
Audience = "test-audience",
33+
ClientCredentials = new List<CredentialDescription>
34+
{
35+
new CredentialDescription { ClientSecret = "test-secret", SourceType = CredentialSource.ClientSecret }
36+
},
37+
38+
// MicrosoftEntraApplicationOptions properties
39+
Name = "test-name",
40+
Instance = "https://login.microsoftonline.com/",
41+
TenantId = "test-tenant-id",
42+
AppHomeTenantId = "test-home-tenant-id",
43+
AzureRegion = "westus",
44+
ClientCapabilities = new List<string> { "cp1" },
45+
SendX5C = true
46+
};
47+
48+
// Act
49+
var tokenAcquirer = factory.GetTokenAcquirer(options);
50+
51+
// Assert
52+
Assert.NotNull(tokenAcquirer);
53+
54+
// Verify the options were properly stored in the merged options
55+
var mergedOptionsStore = provider.GetRequiredService<IMergedOptionsStore>();
56+
var key = DefaultTokenAcquirerFactoryImplementation.GetKey(options.Authority, options.ClientId, options.AzureRegion);
57+
var mergedOptions = mergedOptionsStore.Get(key);
58+
59+
Assert.Equal(options.ClientId, mergedOptions.ClientId);
60+
Assert.Equal(options.EnablePiiLogging, mergedOptions.EnablePiiLogging);
61+
Assert.Equal(options.AllowWebApiToBeAuthorizedByACL, mergedOptions.AllowWebApiToBeAuthorizedByACL);
62+
Assert.Equal(options.Instance, mergedOptions.Instance);
63+
Assert.Equal(options.TenantId, mergedOptions.TenantId);
64+
Assert.Equal(options.AppHomeTenantId, mergedOptions.AppHomeTenantId);
65+
Assert.Equal(options.AzureRegion, mergedOptions.AzureRegion);
66+
Assert.Equal(options.ClientCapabilities, mergedOptions.ClientCapabilities);
67+
Assert.Equal(options.SendX5C, mergedOptions.SendX5C);
68+
}
69+
70+
[Fact]
71+
public void GetTokenAcquirer_WithIdentityApplicationOptions_PropagatesBaseOptions()
72+
{
73+
// Arrange
74+
var taf = new CustomTAF();
75+
var provider = taf.Build();
76+
var factory = provider.GetRequiredService<ITokenAcquirerFactory>();
77+
78+
var options = new IdentityApplicationOptions
79+
{
80+
ClientId = "test-client-id",
81+
Authority = "https://login.microsoftonline.com/test-tenant",
82+
EnablePiiLogging = true,
83+
AllowWebApiToBeAuthorizedByACL = true,
84+
Audience = "test-audience",
85+
ClientCredentials = new List<CredentialDescription>
86+
{
87+
new CredentialDescription { ClientSecret = "test-secret", SourceType = CredentialSource.ClientSecret }
88+
}
89+
};
90+
91+
// Act
92+
var tokenAcquirer = factory.GetTokenAcquirer(options);
93+
94+
// Assert
95+
Assert.NotNull(tokenAcquirer);
96+
97+
// Verify the options were properly stored in the merged options
98+
var mergedOptionsStore = provider.GetRequiredService<IMergedOptionsStore>();
99+
var key = DefaultTokenAcquirerFactoryImplementation.GetKey(options.Authority, options.ClientId, null);
100+
var mergedOptions = mergedOptionsStore.Get(key);
101+
102+
Assert.Equal(options.ClientId, mergedOptions.ClientId);
103+
Assert.Equal(options.EnablePiiLogging, mergedOptions.EnablePiiLogging);
104+
Assert.Equal(options.AllowWebApiToBeAuthorizedByACL, mergedOptions.AllowWebApiToBeAuthorizedByACL);
105+
}
106+
107+
[Fact]
108+
public void GetTokenAcquirer_WithMicrosoftIdentityApplicationOptions_UsesAsIs()
109+
{
110+
// Arrange
111+
var taf = new CustomTAF();
112+
var provider = taf.Build();
113+
var factory = provider.GetRequiredService<ITokenAcquirerFactory>();
114+
115+
var options = new MicrosoftIdentityApplicationOptions
116+
{
117+
ClientId = "test-client-id",
118+
Authority = "https://login.microsoftonline.com/test-tenant",
119+
EnablePiiLogging = true,
120+
AllowWebApiToBeAuthorizedByACL = true,
121+
Instance = "https://login.microsoftonline.com/",
122+
TenantId = "test-tenant-id",
123+
AzureRegion = "westus",
124+
SendX5C = true,
125+
Domain = "test-domain.com",
126+
SignUpSignInPolicyId = "B2C_1_signupsignin"
127+
};
128+
129+
// Act
130+
var tokenAcquirer = factory.GetTokenAcquirer(options);
131+
132+
// Assert
133+
Assert.NotNull(tokenAcquirer);
134+
135+
// Verify the options were properly stored in the merged options
136+
var mergedOptionsStore = provider.GetRequiredService<IMergedOptionsStore>();
137+
var key = DefaultTokenAcquirerFactoryImplementation.GetKey(options.Authority, options.ClientId, options.AzureRegion);
138+
var mergedOptions = mergedOptionsStore.Get(key);
139+
140+
Assert.Equal(options.ClientId, mergedOptions.ClientId);
141+
Assert.Equal(options.EnablePiiLogging, mergedOptions.EnablePiiLogging);
142+
Assert.Equal(options.Instance, mergedOptions.Instance);
143+
Assert.Equal(options.TenantId, mergedOptions.TenantId);
144+
Assert.Equal(options.AzureRegion, mergedOptions.AzureRegion);
145+
Assert.Equal(options.SendX5C, mergedOptions.SendX5C);
146+
Assert.Equal(options.Domain, mergedOptions.Domain);
147+
Assert.Equal(options.SignUpSignInPolicyId, mergedOptions.SignUpSignInPolicyId);
148+
}
149+
150+
private class CustomTAF : TokenAcquirerFactory
151+
{
152+
public CustomTAF()
153+
{
154+
this.Services.AddTokenAcquisition();
155+
this.Services.AddHttpClient();
156+
this.Services.AddSingleton<ITokenAcquirerFactory, DefaultTokenAcquirerFactoryImplementation>();
157+
}
158+
159+
protected override string DefineConfiguration(IConfigurationBuilder builder)
160+
{
161+
return AppContext.BaseDirectory;
162+
}
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)