Skip to content

Commit

Permalink
Port forward the 1.12.1 hotfix
Browse files Browse the repository at this point in the history
  • Loading branch information
christothes committed Sep 27, 2024
1 parent 1b1a2b4 commit dd9c3b9
Show file tree
Hide file tree
Showing 26 changed files with 112 additions and 61 deletions.
10 changes: 3 additions & 7 deletions eng/Packages.Data.props
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,9 @@
<!-- Other approved packages -->
<PackageReference Update="Microsoft.Azure.Amqp" Version="2.6.7" />
<PackageReference Update="Microsoft.Azure.WebPubSub.Common" Version="1.4.0" />
<PackageReference Update="Microsoft.Identity.Client" Version="4.62.0" />
<PackageReference Update="Microsoft.Identity.Client.Extensions.Msal" Version="4.62.0" />
<!--
TODO: This package needs to be released as GA and arch-board approved before taking a dependency in any stable SDK library.
Currently, it is referenced by Azure.Identity.Broker which is still in beta
-->
<PackageReference Update="Microsoft.Identity.Client.Broker" Version="4.62.0" />
<PackageReference Update="Microsoft.Identity.Client" Version="4.65.0" />
<PackageReference Update="Microsoft.Identity.Client.Extensions.Msal" Version="4.65.0" />
<PackageReference Update="Microsoft.Identity.Client.Broker" Version="4.65.0" />

<!-- TODO: Make sure this package is arch-board approved -->
<PackageReference Update="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.35.0" />
Expand Down
1 change: 1 addition & 0 deletions sdk/identity/Azure.Identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Bugs Fixed

- Fixed the request sent in `AzurePipelinesCredential` so it doesn't result in a redirect response when an invalid system access token is provided.
- Updated to version 4.65.0 of Microsoft.Identity.Client to address a bug preventing the use of alternate authority types such as dStS ([4927](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/4927)) .

### Other Changes

Expand Down
15 changes: 15 additions & 0 deletions sdk/identity/Azure.Identity/src/MsalClientBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,20 @@ await _clientWithCaeAsyncLock.GetLockOrValueAsync(true, default).ConfigureAwait(

return asyncLock.HasValue ? asyncLock.Value.Cache : null;
}

public UriBuilder BuildTenantIdWithAuthorityHost(string tenantId)
{
UriBuilder uriBuilder = new(AuthorityHost);
if (uriBuilder.Path.EndsWith("/"))
{
uriBuilder.Path += tenantId;
}
else
{
uriBuilder.Path = uriBuilder.Path + "/" + tenantId;
}

return uriBuilder;
}
}
}
20 changes: 4 additions & 16 deletions sdk/identity/Azure.Identity/src/MsalConfidentialClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,7 @@ public virtual async ValueTask<AuthenticationResult> AcquireTokenForClientCoreAs

if (!string.IsNullOrEmpty(tenantId))
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}
if (!string.IsNullOrEmpty(claims))
Expand Down Expand Up @@ -214,10 +211,7 @@ public virtual async ValueTask<AuthenticationResult> AcquireTokenSilentCoreAsync
var builder = client.AcquireTokenSilent(scopes, account);
if (!string.IsNullOrEmpty(tenantId))
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}
if (!string.IsNullOrEmpty(claims))
Expand Down Expand Up @@ -260,10 +254,7 @@ public virtual async ValueTask<AuthenticationResult> AcquireTokenByAuthorization

if (!string.IsNullOrEmpty(tenantId))
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}
if (!string.IsNullOrEmpty(claims))
Expand Down Expand Up @@ -306,10 +297,7 @@ public virtual async ValueTask<AuthenticationResult> AcquireTokenOnBehalfOfCoreA

if (!string.IsNullOrEmpty(tenantId))
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}
if (!string.IsNullOrEmpty(claims))
Expand Down
25 changes: 5 additions & 20 deletions sdk/identity/Azure.Identity/src/MsalPublicClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,7 @@ protected virtual async ValueTask<AuthenticationResult> AcquireTokenSilentCoreAs
}
if (tenantId != null)
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = TenantId ?? tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}

Expand Down Expand Up @@ -183,10 +180,7 @@ protected virtual async ValueTask<AuthenticationResult> AcquireTokenSilentCoreAs

if (tenantId != null || record.TenantId != null)
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId ?? record.TenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId ?? record.TenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}

Expand Down Expand Up @@ -288,10 +282,7 @@ protected virtual async ValueTask<AuthenticationResult> AcquireTokenInteractiveC
}
if (tenantId != null)
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}
if (browserOptions != null)
Expand Down Expand Up @@ -333,10 +324,7 @@ protected virtual async ValueTask<AuthenticationResult> AcquireTokenByUsernamePa
}
if (!string.IsNullOrEmpty(tenantId))
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenantId
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(tenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}
return await builder.ExecuteAsync(async, cancellationToken)
Expand Down Expand Up @@ -383,10 +371,7 @@ protected virtual async ValueTask<AuthenticationResult> AcquireTokenByRefreshTok

if (!string.IsNullOrEmpty(TenantId))
{
UriBuilder uriBuilder = new UriBuilder(AuthorityHost)
{
Path = tenant
};
UriBuilder uriBuilder = BuildTenantIdWithAuthorityHost(TenantId);
builder.WithTenantIdFromAuthority(uriBuilder.Uri);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
RedirectUri = config.RedirectUri,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
TenantId = config.TenantId,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
AuthorityHost = config.AuthorityHost,
};
var (_, _, processOutput) = CredentialTestHelpers.CreateTokenForAzureCli();
var testProcess = new TestProcess { Output = processOutput };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
TenantId = config.TenantId,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
AuthorityHost = config.AuthorityHost,
};
var (_, _, processOutput) = CredentialTestHelpers.CreateTokenForAzureDeveloperCli();
var testProcess = new TestProcess { Output = processOutput };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
MsalClient = config.MockConfidentialMsalClient,
OidcRequestUri = "https://dev.azure.com/myorg/myproject/_apis/serviceendpoint/endpoints?api-version=2.2.2",
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
TenantId = config.TenantId,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
AuthorityHost = config.AuthorityHost,
};
var (_, _, processOutput) = CredentialTestHelpers.CreateTokenForAzurePowerShell(TimeSpan.FromSeconds(30));
var testProcess = new TestProcess { Output = processOutput };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
MsalClient = config.MockConfidentialMsalClient,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
DisableInstanceDiscovery = config.DisableInstanceDiscovery,
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
DisableInstanceDiscovery = config.DisableInstanceDiscovery,
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
46 changes: 46 additions & 0 deletions sdk/identity/Azure.Identity/tests/CredentialTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,52 @@ public async Task CachingOptionsAreRespected()
Assert.AreEqual(actualToken1.Token, actualToken2.Token);
}

[Test]
public async Task AuthorityHostConfigSupportsdStS()
{
// Configure the transport
var token = Guid.NewGuid().ToString();
TransportConfig transportConfig = new()
{
TokenFactory = req => token,
RequestValidator = req =>
{
if (req.Content != null)
{
var stream = new MemoryStream();
req.Content.WriteTo(stream, default);
var content = new BinaryData(stream.ToArray()).ToString();
var queryString = Uri.UnescapeDataString(content)
.Split('&')
.Select(q => q.Split('='))
.ToDictionary(kvp => kvp[0], kvp => kvp[1]);
}
}
};
var factory = MockTokenTransportFactory(transportConfig);
var mockTransport = new MockTransport(factory);

var config = new CommonCredentialTestConfig()
{
TransportConfig = transportConfig,
Transport = mockTransport,
TenantId = TenantId,
AuthorityHost = new("https://usnorth-passive-dsts.dsts.core.windows.net/dstsv2"),
RedirectUri = new Uri("http://localhost:8400/")
};
var credential = GetTokenCredential(config);
if (!CredentialTestHelpers.IsMsalCredential(credential))
{
Assert.Ignore("EnableCAE tests do not apply to the non-MSAL credentials.");
}
transportConfig.IsPubClient = CredentialTestHelpers.IsCredentialTypePubClient(credential);

// First call to populate the account record for confidential client creds
await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default), default);
var actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Alternate), default);
Assert.AreEqual(token, actualToken.Token);
}

public class MemoryTokenCache : UnsafeTokenCacheOptions
{
public ReadOnlyMemory<byte> Data { get; set; } = new ReadOnlyMemory<byte>();
Expand Down
26 changes: 13 additions & 13 deletions sdk/identity/Azure.Identity/tests/CredentialTestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,15 +404,15 @@ public static bool RequestBodyHasUserAssertionWithHeader(Request req, string hea
return new MockResponse(200);
});

public static byte[] GetMockCacheBytes(string objectId, string userName, string clientId, string tenantId, string token, string refreshToken)
public static byte[] GetMockCacheBytes(string objectId, string userName, string clientId, string tenantId, string token, string refreshToken, string authority = "login.microsoftonline.com")
{
var cacheString = @$"{{
""AccessToken"": {{
""{objectId}.{tenantId}-login.microsoftonline.com-accesstoken-{clientId}-organizations-{MockScopes.Default}"": {{
""{objectId}.{tenantId}-{authority}-accesstoken-{clientId}-organizations-{MockScopes.Default}"": {{
""credential_type"": ""AccessToken"",
""secret"": ""{token}"",
""home_account_id"": ""{objectId}.{tenantId}"",
""environment"": ""login.microsoftonline.com"",
""environment"": ""{authority}"",
""client_id"": ""{clientId}"",
""target"": ""{MockScopes.Default}"",
""realm"": ""organizations"",
Expand All @@ -423,41 +423,41 @@ public static byte[] GetMockCacheBytes(string objectId, string userName, string
}}
}},
""Account"": {{
""{objectId}.{tenantId}-login.microsoftonline.com-organizations"": {{
""{objectId}.{tenantId}-{authority}-organizations"": {{
""home_account_id"": ""{objectId}.{tenantId}"",
""environment"": ""login.microsoftonline.com"",
""environment"": ""{authority}"",
""realm"": ""organizations"",
""local_account_id"": ""{objectId}"",
""username"": ""{userName}"",
""authority_type"": ""MSSTS""
}}
}},
""IdToken"": {{
""{objectId}.{tenantId}-login.microsoftonline.com-idtoken-{clientId}-organizations-"": {{
""{objectId}.{tenantId}-{authority}-idtoken-{clientId}-organizations-"": {{
""credential_type"": ""IdToken"",
""secret"": ""{token}"",
""home_account_id"": ""{objectId}.{tenantId}"",
""environment"": ""login.microsoftonline.com"",
""environment"": ""{authority}"",
""realm"": ""organizations"",
""client_id"": ""{clientId}""
}},
}},
""RefreshToken"": {{
""{objectId}.{tenantId}-login.microsoftonline.com-refreshtoken-{clientId}--{MockScopes.Default}"": {{
""{objectId}.{tenantId}-{authority}-refreshtoken-{clientId}--{MockScopes.Default}"": {{
""credential_type"": ""RefreshToken"",
""secret"": ""{refreshToken}"",
""home_account_id"": ""{objectId}.{tenantId}"",
""environment"": ""login.microsoftonline.com"",
""environment"": ""{authority}"",
""client_id"": ""{clientId}"",
""target"": ""{MockScopes.Default}"",
""last_modification_time"": ""1674853645"",
""family_id"": ""1""
}}
}},
""AppMetadata"": {{
""appmetadata-login.microsoftonline.com-{clientId}"": {{
""appmetadata-{authority}-{clientId}"": {{
""client_id"": ""{clientId}"",
""environment"": ""login.microsoftonline.com"",
""environment"": ""{authority}"",
""family_id"": ""1""
}}
}}
Expand Down Expand Up @@ -489,10 +489,10 @@ public static string CreateMsalClientInfo(string objectId = null, string tenantI
return MsalEncode($"{{\"uid\":\"{uid}\",\"utid\":\"{tid}\"}}");
}

public static string CreateMsalIdToken(string uniqueId, string displayableId, string tenantId)
public static string CreateMsalIdToken(string uniqueId, string displayableId, string tenantId, string authority = "login.microsoftonline.com")
{
string id = "{\"aud\": \"e854a4a7-6c34-449c-b237-fc7a28093d84\"," +
"\"iss\": \"https://login.microsoftonline.com/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/v2.0/\"," +
$"\"iss\": \"https://{authority}/6c3d51dd-f0e5-4959-b4ea-a80c4e36fe5e/v2.0/\"," +
"\"iat\": 1455833828," +
"\"nbf\": 1455833828," +
"\"exp\": 1455837728," +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
AdditionallyAllowedTenants = config.AdditionallyAllowedTenants,
DisableInstanceDiscovery = config.DisableInstanceDiscovery,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
DisableInstanceDiscovery = config.DisableInstanceDiscovery,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
MsalConfidentialClient = config.MockConfidentialMsalClient,
MsalPublicClient = config.MockPublicMsalClient
MsalPublicClient = config.MockPublicMsalClient,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
DisableInstanceDiscovery = config.DisableInstanceDiscovery,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
MsalConfidentialClient = config.MockConfidentialMsalClient,
MsalPublicClient = config.MockPublicMsalClient
MsalPublicClient = config.MockPublicMsalClient,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public override TokenCredential GetTokenCredential(CommonCredentialTestConfig co
DisableInstanceDiscovery = config.DisableInstanceDiscovery,
IsUnsafeSupportLoggingEnabled = config.IsUnsafeSupportLoggingEnabled,
MsalConfidentialClient = config.MockConfidentialMsalClient,
MsalPublicClient = config.MockPublicMsalClient
MsalPublicClient = config.MockPublicMsalClient,
AuthorityHost = config.AuthorityHost,
};
if (config.Transport != null)
{
Expand Down
Loading

0 comments on commit dd9c3b9

Please sign in to comment.