Skip to content

Commit

Permalink
Log troubleshooting headers for AzurePipelinesCredential (#46376)
Browse files Browse the repository at this point in the history
  • Loading branch information
christothes authored Oct 1, 2024
1 parent c5bc53a commit 08581f7
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 7 deletions.
3 changes: 1 addition & 2 deletions sdk/identity/Azure.Identity.Broker/tests/PopTestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ public PopTestClient(TokenCredential credential, ClientOptions options = null)
var pipelineOptions = new HttpPipelineOptions(options);
pipelineOptions.PerRetryPolicies.Add(new PopTokenAuthenticationPolicy(credential, "https://graph.microsoft.com/.default"));
_pipeline = HttpPipelineBuilder.Build(
pipelineOptions,
new HttpPipelineTransportOptions { ServerCertificateCustomValidationCallback = (_) => true });
pipelineOptions);
}

[ForwardsClientCalls(true)]
Expand Down
2 changes: 2 additions & 0 deletions sdk/identity/Azure.Identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

### Other Changes

- Improved error logging for `AzurePipelinesCredential`.

## 1.13.0-beta.2 (2024-09-17)

### Features Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Azure.Identity
/// </summary>
public class AzurePipelinesCredential : TokenCredential
{
private const string Troubleshooting = "See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/azurepipelinescredential/troubleshoot";
internal const string Troubleshooting = "See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/azurepipelinescredential/troubleshoot";
internal readonly string[] AdditionallyAllowedTenantIds;
internal string SystemAccessToken { get; }
internal string TenantId { get; }
Expand Down Expand Up @@ -151,7 +151,10 @@ internal string GetOidcTokenResponse(HttpMessage message)
string error = $"OIDC token not found in response. " + Troubleshooting;
if (message.Response.Status != 200)
{
error = error + $"\n\nResponse= {message.Response.Content}";
var is_x_vss_e2eidValueFound = message.Response.Headers.TryGetValue("x-vss-e2eid", out var x_vss_e2eidValue);
var is_x_msedge_refValueFound = message.Response.Headers.TryGetValue("x-msedge-ref", out var x_msedge_refValue);

error = error + $"\n\nResponse= {message.Response.Content}\n\nx-vss-e2eid= {(is_x_vss_e2eidValueFound ? x_vss_e2eidValue : "Not Found")}\n\nx-msedge-ref= {(is_x_msedge_refValueFound ? x_msedge_refValue : "Not Found")}";
}
throw new AuthenticationFailedException(error);
}
Expand Down
13 changes: 10 additions & 3 deletions sdk/identity/Azure.Identity/tests/AzurePipelinesCredentialTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,11 @@ public void AzurePipelineCredentialReturnsErrorInformation()
var mockTransport = new MockTransport(req => new MockResponse(200).WithContent(
$"{{\"token_type\": \"Bearer\",\"expires_in\": 9999,\"ext_expires_in\": 9999,\"access_token\": \"mytoken\" }}"));

var options = new AzurePipelinesCredentialOptions { Transport = mockTransport };
var options = new AzurePipelinesCredentialOptions { Transport = mockTransport, OidcRequestUri = "https://mockCollectionUri" };
var cred = new AzurePipelinesCredential(tenantId, clientId, serviceConnectionId, systemAccessToken, options);

Assert.ThrowsAsync<AuthenticationFailedException>(async () => await cred.GetTokenAsync(new TokenRequestContext(new[] { "scope" }), CancellationToken.None));
var ex = Assert.ThrowsAsync<AuthenticationFailedException>(async () => await cred.GetTokenAsync(new TokenRequestContext(new[] { "scope" }), CancellationToken.None));
Assert.That(ex.Message, Does.Contain(AzurePipelinesCredential.Troubleshooting));
}
}

Expand All @@ -140,7 +141,10 @@ public void AzurePipelineCredentialReturnsNonJsonErrorInformation(int responseSt
{
if (req.Uri.Host == "mockcollectionuri")
{
return new MockResponse(responseStatusCode).WithContent($"< not json, but an error >");
return new MockResponse(responseStatusCode)
.WithContent($"< not json, but an error >")
.WithHeader("x-vss-e2eid", "myE2EId")
.WithHeader("x-msedge-ref", "myRef");
}
return new MockResponse(200).WithContent(
$"{{\"token_type\": \"Bearer\",\"expires_in\": 9999,\"ext_expires_in\": 9999,\"access_token\": \"mytoken\" }}");
Expand All @@ -158,6 +162,9 @@ public void AzurePipelineCredentialReturnsNonJsonErrorInformation(int responseSt
else
{
Assert.That(ex.Message, Does.Contain("< not json, but an error >"));
Assert.That(ex.Message, Does.Contain(AzurePipelinesCredential.Troubleshooting));
Assert.That(ex.Message, Does.Contain("myE2EId"));
Assert.That(ex.Message, Does.Contain("myRef"));
}
}
}
Expand Down

0 comments on commit 08581f7

Please sign in to comment.