From 7d9e5f4bc2ed653ac3253a162d21554ab6cfaf4f Mon Sep 17 00:00:00 2001 From: Christopher Scott Date: Thu, 31 Mar 2022 17:59:41 -0500 Subject: [PATCH] Add troubleshooting aka link for ClientCertificateCredential (#27825) --- .../ClientCertificateCredential.cs | 6 +++--- .../tests/ClientCertificateCredentialTests.cs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sdk/identity/Azure.Identity/src/Credentials/ClientCertificateCredential.cs b/sdk/identity/Azure.Identity/src/Credentials/ClientCertificateCredential.cs index f8f1d98a6ede..09a2614eb5dd 100644 --- a/sdk/identity/Azure.Identity/src/Credentials/ClientCertificateCredential.cs +++ b/sdk/identity/Azure.Identity/src/Credentials/ClientCertificateCredential.cs @@ -5,8 +5,6 @@ using Azure.Core.Pipeline; using Microsoft.Identity.Client; using System; -using System.Collections.Generic; -using System.IO; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -20,6 +18,8 @@ namespace Azure.Identity /// public class ClientCertificateCredential : TokenCredential { + internal const string Troubleshooting = "See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/clientcertificatecredential/troubleshoot"; + /// /// Gets the Azure Active Directory tenant (directory) Id of the service principal /// @@ -181,7 +181,7 @@ public override AccessToken GetToken(TokenRequestContext requestContext, Cancell } catch (Exception e) { - throw scope.FailWrapAndThrow(e); + throw scope.FailWrapAndThrow(e, Troubleshooting); } } diff --git a/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs b/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs index 3d6ffeb8626d..dde3a4f5f05d 100644 --- a/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs +++ b/sdk/identity/Azure.Identity/tests/ClientCertificateCredentialTests.cs @@ -86,6 +86,25 @@ public void VerifyBadCertificateFileBehavior() Assert.ThrowsAsync(async () => await unsupportedCertCredential.GetTokenAsync(tokenContext)); } + public async Task ExceptionContainsTroubleshootingLink() + { + var response = new MockResponse(400); + response.SetContent($"{{ \"error_code\": \"InvalidSecret\", \"message\": \"The specified client_secret is incorrect\" }}"); + var mockTransport = new MockTransport(response); + var options = new TokenCredentialOptions() { Transport = mockTransport }; + var expectedTenantId = Guid.NewGuid().ToString(); + var expectedClientId = Guid.NewGuid().ToString(); + var certificatePath = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data", "cert.pfx"); + var certificatePathPem = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data", "cert.pem"); + var mockCert = new X509Certificate2(certificatePath); + + ClientCertificateCredential credential = InstrumentClient(new ClientCertificateCredential(expectedTenantId, expectedClientId, mockCert, options)); + + var exception = Assert.ThrowsAsync(async () => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default))); + Assert.That(exception.Message, Does.Contain(ClientCertificateCredential.Troubleshooting)); + await Task.CompletedTask; + } + [TestCase(true)] [TestCase(false)] public async Task VerifyClientCertificateRequestFailedAsync(bool usePemFile)