Skip to content

Commit b81b267

Browse files
authored
Make PowershellCredential token parsing locale agnostic (Azure#38191)
1 parent 0ebfd44 commit b81b267

File tree

4 files changed

+10
-7
lines changed

4 files changed

+10
-7
lines changed

sdk/identity/Azure.Identity/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
### Bugs Fixed
1111

1212
- ManagedIdentityCredential will no longer attempt to parse invalid json payloads on responses from the managed identity endpoint.
13+
- 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)
1314

1415
### Other Changes
1516

sdk/identity/Azure.Identity/src/Credentials/AzurePowerShellCredential.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ private static void CheckForErrors(string output)
202202

203203
private static void ValidateResult(string output)
204204
{
205-
if (output.IndexOf("Microsoft.Azure.Commands.Profile.Models.PSAccessToken", StringComparison.OrdinalIgnoreCase) < 0)
205+
if (output.IndexOf(@"<Property Name=""Token"" Type=""System.String"">", StringComparison.OrdinalIgnoreCase) < 0)
206206
{
207207
throw new CredentialUnavailableException("PowerShell did not return a valid response.");
208208
}
@@ -246,8 +246,11 @@ private void GetFileNameAndArguments(string resource, string tenantId, out strin
246246
}}
247247
248248
$token = Get-AzAccessToken -ResourceUrl '{resource}'{tenantIdArg}
249+
$customToken = New-Object -TypeName psobject
250+
$customToken | Add-Member -MemberType NoteProperty -Name Token -Value $token.Token
251+
$customToken | Add-Member -MemberType NoteProperty -Name ExpiresOn -Value $token.ExpiresOn.ToUnixTimeSeconds()
249252
250-
$x = $token | ConvertTo-Xml
253+
$x = $customToken | ConvertTo-Xml
251254
return $x.Objects.FirstChild.OuterXml
252255
";
253256

@@ -285,7 +288,7 @@ private static AccessToken DeserializeOutput(string output)
285288
break;
286289

287290
case "ExpiresOn":
288-
expiresOn = DateTimeOffset.Parse(e.Value, CultureInfo.CurrentCulture).ToUniversalTime();
291+
expiresOn = DateTimeOffset.FromUnixTimeSeconds(long.Parse(e.Value));
289292
break;
290293
}
291294

sdk/identity/Azure.Identity/tests/AzurePowerShellCredentialsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace Azure.Identity.Tests
1818
public class AzurePowerShellCredentialsTests : CredentialTestBase<AzurePowerShellCredentialOptions>
1919
{
2020
private string tokenXML =
21-
"<Object Type=\"Microsoft.Azure.Commands.Profile.Models.PSAccessToken\"><Property Name=\"Token\" Type=\"System.String\">Kg==</Property><Property Name=\"ExpiresOn\" Type=\"System.DateTimeOffset\">5/11/2021 8:20:03 PM +00:00</Property><Property Name=\"TenantId\" Type=\"System.String\">72f988bf-86f1-41af-91ab-2d7cd011db47</Property><Property Name=\"UserId\" Type=\"System.String\">chriss@microsoft.com</Property><Property Name=\"Type\" Type=\"System.String\">Bearer</Property></Object>";
21+
@"<Object Type=""System.Management.Automation.PSCustomObject""><Property Name=""Token"" Type=""System.String"">Kg==</Property><Property Name=""ExpiresOn"" Type=""System.Int64"">1692035272</Property></Object>";
2222

2323
public AzurePowerShellCredentialsTests(bool isAsync) : base(isAsync)
2424
{ }

sdk/identity/Azure.Identity/tests/CredentialTestHelpers.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ public static (string Token, DateTimeOffset ExpiresOn, string Json) CreateTokenF
6969

7070
public static (string Token, DateTimeOffset ExpiresOn, string Json) CreateTokenForAzurePowerShell(TimeSpan expiresOffset)
7171
{
72-
var expiresOnString = DateTimeOffset.Now.Add(expiresOffset).ToString();
73-
var expiresOn = DateTimeOffset.Parse(expiresOnString, CultureInfo.CurrentCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal);
72+
var expiresOn = DateTimeOffset.FromUnixTimeSeconds(DateTimeOffset.UtcNow.Add(expiresOffset).ToUnixTimeSeconds());
7473
var token = TokenGenerator.GenerateToken(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), expiresOn.UtcDateTime);
75-
var xml = @$"<Object Type=""Microsoft.Azure.Commands.Profile.Models.PSAccessToken""><Property Name=""Token"" Type=""System.String"">{token}</Property><Property Name=""ExpiresOn"" Type=""System.DateTimeOffset"">{expiresOnString}</Property><Property Name=""TenantId"" Type=""System.String"">{Guid.NewGuid().ToString()}</Property><Property Name=""UserId"" Type=""System.String"">foo@contoso.com</Property><Property Name=""Type"" Type=""System.String"">Bearer</Property></Object>";
74+
var xml = @$"<Object Type=""System.Management.Automation.PSCustomObject""><Property Name=""Token"" Type=""System.String"">{token}</Property><Property Name=""ExpiresOn"" Type=""System.Int64"">{expiresOn.ToUnixTimeSeconds()}</Property></Object>";
7675
return (token, expiresOn, xml);
7776
}
7877

0 commit comments

Comments
 (0)