From b81b2676ff17622a6cf829e11c579301c01d70f3 Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Mon, 14 Aug 2023 15:10:23 -0500 Subject: [PATCH] Make PowershellCredential token parsing locale agnostic (#38191) --- sdk/identity/Azure.Identity/CHANGELOG.md | 1 + .../src/Credentials/AzurePowerShellCredential.cs | 9 ++++++--- .../tests/AzurePowerShellCredentialsTests.cs | 2 +- .../Azure.Identity/tests/CredentialTestHelpers.cs | 5 ++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sdk/identity/Azure.Identity/CHANGELOG.md b/sdk/identity/Azure.Identity/CHANGELOG.md index 9233c04c5d10f..1fc3336bb1483 100644 --- a/sdk/identity/Azure.Identity/CHANGELOG.md +++ b/sdk/identity/Azure.Identity/CHANGELOG.md @@ -10,6 +10,7 @@ ### Bugs Fixed - ManagedIdentityCredential will no longer attempt to parse invalid json payloads on responses from the managed identity endpoint. +- Fixed an issue where AzurePowerShellCredential fails to parse the token response from Azure PowerShell. [#22638](https://github.com/Azure/azure-sdk-for-net/issues/22638) ### Other Changes diff --git a/sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCredential.cs b/sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCredential.cs index c5c0c1f596cf6..5dffc88692832 100644 --- a/sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCredential.cs +++ b/sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCredential.cs @@ -202,7 +202,7 @@ private static void CheckForErrors(string output) private static void ValidateResult(string output) { - if (output.IndexOf("Microsoft.Azure.Commands.Profile.Models.PSAccessToken", StringComparison.OrdinalIgnoreCase) < 0) + if (output.IndexOf(@"", StringComparison.OrdinalIgnoreCase) < 0) { throw new CredentialUnavailableException("PowerShell did not return a valid response."); } @@ -246,8 +246,11 @@ private void GetFileNameAndArguments(string resource, string tenantId, out strin }} $token = Get-AzAccessToken -ResourceUrl '{resource}'{tenantIdArg} +$customToken = New-Object -TypeName psobject +$customToken | Add-Member -MemberType NoteProperty -Name Token -Value $token.Token +$customToken | Add-Member -MemberType NoteProperty -Name ExpiresOn -Value $token.ExpiresOn.ToUnixTimeSeconds() -$x = $token | ConvertTo-Xml +$x = $customToken | ConvertTo-Xml return $x.Objects.FirstChild.OuterXml "; @@ -285,7 +288,7 @@ private static AccessToken DeserializeOutput(string output) break; case "ExpiresOn": - expiresOn = DateTimeOffset.Parse(e.Value, CultureInfo.CurrentCulture).ToUniversalTime(); + expiresOn = DateTimeOffset.FromUnixTimeSeconds(long.Parse(e.Value)); break; } diff --git a/sdk/identity/Azure.Identity/tests/AzurePowerShellCredentialsTests.cs b/sdk/identity/Azure.Identity/tests/AzurePowerShellCredentialsTests.cs index 50876b994d4df..ae5fbc67c008f 100644 --- a/sdk/identity/Azure.Identity/tests/AzurePowerShellCredentialsTests.cs +++ b/sdk/identity/Azure.Identity/tests/AzurePowerShellCredentialsTests.cs @@ -18,7 +18,7 @@ namespace Azure.Identity.Tests public class AzurePowerShellCredentialsTests : CredentialTestBase { private string tokenXML = - "Kg==5/11/2021 8:20:03 PM +00:0072f988bf-86f1-41af-91ab-2d7cd011db47chriss@microsoft.comBearer"; + @"Kg==1692035272"; public AzurePowerShellCredentialsTests(bool isAsync) : base(isAsync) { } diff --git a/sdk/identity/Azure.Identity/tests/CredentialTestHelpers.cs b/sdk/identity/Azure.Identity/tests/CredentialTestHelpers.cs index 477809df422e4..74b1c7d9ea7a5 100644 --- a/sdk/identity/Azure.Identity/tests/CredentialTestHelpers.cs +++ b/sdk/identity/Azure.Identity/tests/CredentialTestHelpers.cs @@ -69,10 +69,9 @@ public static (string Token, DateTimeOffset ExpiresOn, string Json) CreateTokenF public static (string Token, DateTimeOffset ExpiresOn, string Json) CreateTokenForAzurePowerShell(TimeSpan expiresOffset) { - var expiresOnString = DateTimeOffset.Now.Add(expiresOffset).ToString(); - var expiresOn = DateTimeOffset.Parse(expiresOnString, CultureInfo.CurrentCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal); + var expiresOn = DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.Add(expiresOffset).ToUnixTimeSeconds()); var token = TokenGenerator.GenerateToken(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), expiresOn.UtcDateTime); - var xml = @$"{token}{expiresOnString}{Guid.NewGuid().ToString()}foo@contoso.comBearer"; + var xml = @$"{token}{expiresOn.ToUnixTimeSeconds()}"; return (token, expiresOn, xml); }