From 56d245d96847c2fbd789d7cbc1ed49645e6b31a0 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 20 Sep 2024 12:52:24 -0700 Subject: [PATCH 1/2] Updated the request header sent to the OIDC endpoint in so it doesn't result in a redirect response when an invalid system access token is provided. --- sdk/identity/azure-identity/CHANGELOG.md | 2 ++ sdk/identity/azure-identity/TROUBLESHOOTING.md | 2 +- .../azure-identity/src/azure_pipelines_credential.cpp | 1 + .../test/ut/azure_pipelines_credential_test.cpp | 5 +++-- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 7fe92a6f7b..25e0aec81e 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -8,6 +8,8 @@ ### 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. + ### Other Changes ## 1.10.0-beta.1 (2024-09-17) diff --git a/sdk/identity/azure-identity/TROUBLESHOOTING.md b/sdk/identity/azure-identity/TROUBLESHOOTING.md index 3f9c49def4..fe5099bfa0 100644 --- a/sdk/identity/azure-identity/TROUBLESHOOTING.md +++ b/sdk/identity/azure-identity/TROUBLESHOOTING.md @@ -40,7 +40,7 @@ az account get-access-token --output json --resource https://management.core.win |---|---|---| | AADSTS900023: Specified tenant identifier `` is neither a valid DNS name, nor a valid external domain.|The `tenantId` argument to the `AzurePipelinesCredential` constructor is incorrect| Verify the tenant ID. It must identify the tenant of the user-assigned managed identity or service principal configured for the service connection.| | No service connection found with identifier `` |The `serviceConnectionId` argument to the `AzurePipelinesCredential` constructor is incorrect| Verify the service connection ID. This parameter refers to the `resourceId` of the Azure Service Connection. It can also be found in the query string of the service connection's configuration in Azure DevOps. [Azure Pipelines documentation](https://learn.microsoft.com/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml) has more information about service connections.| -|302 (Found) response from OIDC endpoint|The `systemAccessToken` argument to the `AzurePipelinesCredential` constructor is incorrect|Check pipeline configuration. This value comes from the predefined variable `System.AccessToken` [as described in Azure Pipelines documentation](https://learn.microsoft.com/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken).| +|401 (Unauthorized) response from OIDC endpoint|The `systemAccessToken` argument to the `AzurePipelinesCredential` constructor is incorrect|Check pipeline configuration. This value comes from the predefined variable `System.AccessToken` [as described in Azure Pipelines documentation](https://learn.microsoft.com/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken).| |No value for environment variable `SYSTEM_OIDCREQUESTURI` needed by AzurePipelinesCredential. This should be set by Azure Pipelines. AuthenticationException: AzurePipelinesCredential authentication unavailable.|This code is not running inside of the Azure Pipelines environment. You may be running this code locally or on some other environment.|This credential is only designed to run inside the Azure Pipelines environment for the federated identity to work.| |AADSTS700016: Application with identifier 'clientId' was not found in the directory 'Microsoft'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.|The `` provided is invalid|Verify the client ID argument is valid. If the service connection's federated identity was registered via a user-assigned managed identity, the client ID of the managed identity should be provided. If the service connection's federated identity is registered via an app registration, the Application (client) ID from your app registration should be provided.| diff --git a/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp b/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp index 3665fe6a5b..a88233177b 100644 --- a/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp +++ b/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp @@ -103,6 +103,7 @@ Request AzurePipelinesCredential::CreateOidcRequestMessage() const Request request = Request(HttpMethod::Post, requestUrl); request.SetHeader("content-type", "application/json"); request.SetHeader("authorization", "Bearer " + m_systemAccessToken); + request.SetHeader("X-TFS-FedAuthRedirect", "Suppress"); return request; } diff --git a/sdk/identity/azure-identity/test/ut/azure_pipelines_credential_test.cpp b/sdk/identity/azure-identity/test/ut/azure_pipelines_credential_test.cpp index 07167abc7c..3a7aa331c8 100644 --- a/sdk/identity/azure-identity/test/ut/azure_pipelines_credential_test.cpp +++ b/sdk/identity/azure-identity/test/ut/azure_pipelines_credential_test.cpp @@ -644,7 +644,7 @@ TEST(AzurePipelinesCredential, InvalidServiceConnectionId_LIVEONLY_) } } -TEST(AzurePipelinesCredential, DISABLED_InvalidSystemAccessToken_LIVEONLY_) +TEST(AzurePipelinesCredential, InvalidSystemAccessToken_LIVEONLY_) { std::string tenantId = Environment::GetVariable("AZURESUBSCRIPTION_TENANT_ID"); std::string clientId = Environment::GetVariable("AZURESUBSCRIPTION_CLIENT_ID"); @@ -673,6 +673,7 @@ TEST(AzurePipelinesCredential, DISABLED_InvalidSystemAccessToken_LIVEONLY_) } catch (AuthenticationException const& ex) { - EXPECT_TRUE(std::string(ex.what()).find("302 (Found)") != std::string::npos) << ex.what(); + EXPECT_TRUE(std::string(ex.what()).find("401 (Unauthorized)") != std::string::npos) + << ex.what(); } } From b5e47946a51a3b5abf9e4a7adeaad1dd59efa099 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 20 Sep 2024 17:08:33 -0700 Subject: [PATCH 2/2] Add comment on what X-TFS-FedAuthRedirect does. --- sdk/identity/azure-identity/src/azure_pipelines_credential.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp b/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp index a88233177b..5a83c96385 100644 --- a/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp +++ b/sdk/identity/azure-identity/src/azure_pipelines_credential.cpp @@ -103,6 +103,8 @@ Request AzurePipelinesCredential::CreateOidcRequestMessage() const Request request = Request(HttpMethod::Post, requestUrl); request.SetHeader("content-type", "application/json"); request.SetHeader("authorization", "Bearer " + m_systemAccessToken); + + // Prevents the service from responding with a redirect HTTP status code (useful for automation). request.SetHeader("X-TFS-FedAuthRedirect", "Suppress"); return request;