From 60dff1dac10cd2f97df277ad7819c69981702998 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 2 Aug 2024 16:06:04 -0700 Subject: [PATCH] Pull beta-only changes out of identity for the August GA release (#5863) * Revert "Add support for providing a Resource ID to ManagedIdentityCredential. (#5832)" This reverts commit 193bbe69634e4639a4c2b9df9f716c73c6cd9479. * Revert "Add support for customizing the IMDS endpoint within ManagedIdentityCredential using an env var. (#5834)" This reverts commit 00304a0556491e42442bdf497152b21d8e51f9f8. --- .vscode/cspell.json | 1 - .../identity/managed_identity_credential.hpp | 34 -- .../src/managed_identity_credential.cpp | 15 +- .../src/managed_identity_source.cpp | 52 +- .../src/private/managed_identity_source.hpp | 13 - .../azure-identity/test/ut/CMakeLists.txt | 1 - .../ut/managed_identity_credential_test.cpp | 504 ------------------ .../test/ut/resource_identifier_test.cpp | 18 - 8 files changed, 11 insertions(+), 627 deletions(-) delete mode 100644 sdk/identity/azure-identity/test/ut/resource_identifier_test.cpp diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 56f4961c5..36885d792 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -132,7 +132,6 @@ "hlocal", "HLOCAL", "HRESULT", - "imds", "Imds", "IMDS", "immutability", diff --git a/sdk/identity/azure-identity/inc/azure/identity/managed_identity_credential.hpp b/sdk/identity/azure-identity/inc/azure/identity/managed_identity_credential.hpp index bbeec211b..569f443f0 100644 --- a/sdk/identity/azure-identity/inc/azure/identity/managed_identity_credential.hpp +++ b/sdk/identity/azure-identity/inc/azure/identity/managed_identity_credential.hpp @@ -19,29 +19,6 @@ namespace Azure { namespace Identity { class ManagedIdentitySource; } - // This will move to Azure::Core. - /** - * @brief An Azure Resource Manager resource identifier. - */ - class ResourceIdentifier final { - std::string m_resourceId; - - public: - /** - * @brief Constructs a resource identifier. - * - * @param resourceId The id string to create the ResourceIdentifier from. - */ - explicit ResourceIdentifier(std::string const& resourceId) : m_resourceId(resourceId){}; - - /** - * @brief The string representation of this resource identifier. - * - * @return The resource identifier string. - */ - std::string ToString() const { return m_resourceId; } - }; - /** * @brief Attempts authentication using a managed identity that has been assigned to the * deployment environment. This authentication type works in Azure VMs, App Service and Azure @@ -71,17 +48,6 @@ namespace Azure { namespace Identity { Azure::Core::Credentials::TokenCredentialOptions const& options = Azure::Core::Credentials::TokenCredentialOptions()); - /** - * @brief Constructs an instance of ManagedIdentityCredential capable of authenticating a - * resource with a user-assigned managed identity. - * - * @param resourceId The resource ID to authenticate for a user-assigned managed identity. - * @param options Options for token retrieval. - */ - explicit ManagedIdentityCredential( - ResourceIdentifier const& resourceId, - Azure::Core::Credentials::TokenCredentialOptions const& options = {}); - /** * @brief Constructs a Managed Identity Credential. * diff --git a/sdk/identity/azure-identity/src/managed_identity_credential.cpp b/sdk/identity/azure-identity/src/managed_identity_credential.cpp index bcb97d646..7ebfc5cdf 100644 --- a/sdk/identity/azure-identity/src/managed_identity_credential.cpp +++ b/sdk/identity/azure-identity/src/managed_identity_credential.cpp @@ -11,7 +11,6 @@ namespace { std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource( std::string const& credentialName, std::string const& clientId, - std::string const& resourceId, Azure::Core::Credentials::TokenCredentialOptions const& options) { using namespace Azure::Core::Credentials; @@ -19,7 +18,6 @@ std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource( static std::unique_ptr (*managedIdentitySourceCreate[])( std::string const& credName, std::string const& clientId, - std::string const& resourceId, TokenCredentialOptions const& options) = {AppServiceV2019ManagedIdentitySource::Create, AppServiceV2017ManagedIdentitySource::Create, @@ -31,7 +29,7 @@ std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource( // For that reason, it is not possible to cover that execution branch in tests. for (auto create : managedIdentitySourceCreate) { - if (auto source = create(credentialName, clientId, resourceId, options)) + if (auto source = create(credentialName, clientId, options)) { return source; } @@ -49,16 +47,7 @@ ManagedIdentityCredential::ManagedIdentityCredential( Azure::Core::Credentials::TokenCredentialOptions const& options) : TokenCredential("ManagedIdentityCredential") { - m_managedIdentitySource = CreateManagedIdentitySource(GetCredentialName(), clientId, {}, options); -} - -ManagedIdentityCredential::ManagedIdentityCredential( - ResourceIdentifier const& resourceId, - Azure::Core::Credentials::TokenCredentialOptions const& options) - : TokenCredential("ManagedIdentityCredential") -{ - m_managedIdentitySource - = CreateManagedIdentitySource(GetCredentialName(), {}, resourceId.ToString(), options); + m_managedIdentitySource = CreateManagedIdentitySource(GetCredentialName(), clientId, options); } ManagedIdentityCredential::ManagedIdentityCredential( diff --git a/sdk/identity/azure-identity/src/managed_identity_source.cpp b/sdk/identity/azure-identity/src/managed_identity_source.cpp index fccdb26dd..1b7d6467e 100644 --- a/sdk/identity/azure-identity/src/managed_identity_source.cpp +++ b/sdk/identity/azure-identity/src/managed_identity_source.cpp @@ -140,7 +140,6 @@ template std::unique_ptr AppServiceManagedIdentitySource::Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Azure::Core::Credentials::TokenCredentialOptions const& options, char const* endpointVarName, char const* secretVarName, @@ -155,7 +154,6 @@ std::unique_ptr AppServiceManagedIdentitySource::Create( { return std::unique_ptr(new T( clientId, - resourceId, options, ParseEndpointUrl(credName, msiEndpoint, endpointVarName, credSource), msiSecret)); @@ -167,7 +165,6 @@ std::unique_ptr AppServiceManagedIdentitySource::Create( AppServiceManagedIdentitySource::AppServiceManagedIdentitySource( std::string const& clientId, - std::string const& resourceId, Azure::Core::Credentials::TokenCredentialOptions const& options, Azure::Core::Url endpointUrl, std::string const& secret, @@ -183,17 +180,10 @@ AppServiceManagedIdentitySource::AppServiceManagedIdentitySource( url.AppendQueryParameter("api-version", apiVersion); - // Only one of clientId or resourceId will be set to a non-empty value. - // AppService uses mi_res_id, and not msi_res_id: - // https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp#rest-endpoint-reference if (!clientId.empty()) { url.AppendQueryParameter(clientIdHeaderName, clientId); } - else if (!resourceId.empty()) - { - url.AppendQueryParameter("mi_res_id", resourceId); - } } m_request.SetHeader(secretHeaderName, secret); @@ -233,28 +223,24 @@ Azure::Core::Credentials::AccessToken AppServiceManagedIdentitySource::GetToken( std::unique_ptr AppServiceV2017ManagedIdentitySource::Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options) { return AppServiceManagedIdentitySource::Create( - credName, clientId, resourceId, options, "MSI_ENDPOINT", "MSI_SECRET", "2017"); + credName, clientId, options, "MSI_ENDPOINT", "MSI_SECRET", "2017"); } std::unique_ptr AppServiceV2019ManagedIdentitySource::Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options) { return AppServiceManagedIdentitySource::Create( - credName, clientId, resourceId, options, "IDENTITY_ENDPOINT", "IDENTITY_HEADER", "2019"); + credName, clientId, options, "IDENTITY_ENDPOINT", "IDENTITY_HEADER", "2019"); } -// Cloud Shell doesn't support user-assigned managed identities std::unique_ptr CloudShellManagedIdentitySource::Create( std::string const& credName, std::string const& clientId, - std::string const&, Azure::Core::Credentials::TokenCredentialOptions const& options) { constexpr auto EndpointVarName = "MSI_ENDPOINT"; @@ -329,7 +315,6 @@ Azure::Core::Credentials::AccessToken CloudShellManagedIdentitySource::GetToken( std::unique_ptr AzureArcManagedIdentitySource::Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Azure::Core::Credentials::TokenCredentialOptions const& options) { using Azure::Core::Credentials::AuthenticationException; @@ -345,11 +330,11 @@ std::unique_ptr AzureArcManagedIdentitySource::Create( return nullptr; } - if (!clientId.empty() || !resourceId.empty()) + if (!clientId.empty()) { throw AuthenticationException( "User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. " - "To authenticate with the system assigned identity, omit the client or resource ID " + "To authenticate with the system assigned identity, omit the client ID " "when constructing the ManagedIdentityCredential."); } @@ -363,6 +348,7 @@ AzureArcManagedIdentitySource::AzureArcManagedIdentitySource( : ManagedIdentitySource(std::string(), endpointUrl.GetHost(), options), m_url(std::move(endpointUrl)) { + m_url.AppendQueryParameter("api-version", "2019-11-01"); } @@ -456,7 +442,6 @@ Azure::Core::Credentials::AccessToken AzureArcManagedIdentitySource::GetToken( std::unique_ptr ImdsManagedIdentitySource::Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Azure::Core::Credentials::TokenCredentialOptions const& options) { IdentityLog::Write( @@ -464,28 +449,16 @@ std::unique_ptr ImdsManagedIdentitySource::Create( credName + " will be created" + WithSourceMessage("Azure Instance Metadata Service") + ".\nSuccessful creation does not guarantee further successful token retrieval."); - std::string imdsHost = "http://169.254.169.254"; - std::string customImdsHost = Environment::GetVariable("AZURE_IMDS_CUSTOM_AUTHORITY_HOST"); - if (!customImdsHost.empty()) - { - IdentityLog::Write( - IdentityLog::Level::Informational, "Custom IMDS host is set to: " + customImdsHost); - imdsHost = customImdsHost; - } - Azure::Core::Url imdsUrl(imdsHost); - imdsUrl.AppendPath("/metadata/identity/oauth2/token"); - - return std::unique_ptr( - new ImdsManagedIdentitySource(clientId, resourceId, imdsUrl, options)); + return std::unique_ptr(new ImdsManagedIdentitySource(clientId, options)); } ImdsManagedIdentitySource::ImdsManagedIdentitySource( std::string const& clientId, - std::string const& resourceId, - Azure::Core::Url const& imdsUrl, Azure::Core::Credentials::TokenCredentialOptions const& options) : ManagedIdentitySource(clientId, std::string(), options), - m_request(Azure::Core::Http::HttpMethod::Get, imdsUrl) + m_request( + Azure::Core::Http::HttpMethod::Get, + Azure::Core::Url("http://169.254.169.254/metadata/identity/oauth2/token")) { { using Azure::Core::Url; @@ -493,17 +466,10 @@ ImdsManagedIdentitySource::ImdsManagedIdentitySource( url.AppendQueryParameter("api-version", "2018-02-01"); - // Only one of clientId or resourceId will be set to a non-empty value. - // IMDS uses msi_res_id, and not mi_res_id: - // https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http if (!clientId.empty()) { url.AppendQueryParameter("client_id", clientId); } - else if (!resourceId.empty()) - { - url.AppendQueryParameter("msi_res_id", resourceId); - } } m_request.SetHeader("Metadata", "true"); diff --git a/sdk/identity/azure-identity/src/private/managed_identity_source.hpp b/sdk/identity/azure-identity/src/private/managed_identity_source.hpp index b7f7e6a82..2b5e9e96f 100644 --- a/sdk/identity/azure-identity/src/private/managed_identity_source.hpp +++ b/sdk/identity/azure-identity/src/private/managed_identity_source.hpp @@ -54,7 +54,6 @@ namespace Azure { namespace Identity { namespace _detail { protected: explicit AppServiceManagedIdentitySource( std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options, Core::Url endpointUrl, std::string const& secret, @@ -66,7 +65,6 @@ namespace Azure { namespace Identity { namespace _detail { static std::unique_ptr Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options, char const* endpointVarName, char const* secretVarName, @@ -84,13 +82,11 @@ namespace Azure { namespace Identity { namespace _detail { private: explicit AppServiceV2017ManagedIdentitySource( std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options, Core::Url endpointUrl, std::string const& secret) : AppServiceManagedIdentitySource( clientId, - resourceId, options, endpointUrl, secret, @@ -104,7 +100,6 @@ namespace Azure { namespace Identity { namespace _detail { static std::unique_ptr Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options); }; @@ -114,13 +109,11 @@ namespace Azure { namespace Identity { namespace _detail { private: explicit AppServiceV2019ManagedIdentitySource( std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options, Core::Url endpointUrl, std::string const& secret) : AppServiceManagedIdentitySource( clientId, - resourceId, options, endpointUrl, secret, @@ -134,7 +127,6 @@ namespace Azure { namespace Identity { namespace _detail { static std::unique_ptr Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options); }; @@ -152,7 +144,6 @@ namespace Azure { namespace Identity { namespace _detail { static std::unique_ptr Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::AccessToken GetToken( @@ -172,7 +163,6 @@ namespace Azure { namespace Identity { namespace _detail { static std::unique_ptr Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::AccessToken GetToken( @@ -186,15 +176,12 @@ namespace Azure { namespace Identity { namespace _detail { explicit ImdsManagedIdentitySource( std::string const& clientId, - std::string const& resourceId, - Core::Url const& imdsUrl, Core::Credentials::TokenCredentialOptions const& options); public: static std::unique_ptr Create( std::string const& credName, std::string const& clientId, - std::string const& resourceId, Core::Credentials::TokenCredentialOptions const& options); Core::Credentials::AccessToken GetToken( diff --git a/sdk/identity/azure-identity/test/ut/CMakeLists.txt b/sdk/identity/azure-identity/test/ut/CMakeLists.txt index 3b2bbee69..fe44d0c43 100644 --- a/sdk/identity/azure-identity/test/ut/CMakeLists.txt +++ b/sdk/identity/azure-identity/test/ut/CMakeLists.txt @@ -28,7 +28,6 @@ add_executable ( environment_credential_test.cpp macro_guard_test.cpp managed_identity_credential_test.cpp - resource_identifier_test.cpp simplified_header_test.cpp tenant_id_resolver_test.cpp token_cache_test.cpp diff --git a/sdk/identity/azure-identity/test/ut/managed_identity_credential_test.cpp b/sdk/identity/azure-identity/test/ut/managed_identity_credential_test.cpp index e182a5ea8..edad7e6f4 100644 --- a/sdk/identity/azure-identity/test/ut/managed_identity_credential_test.cpp +++ b/sdk/identity/azure-identity/test/ut/managed_identity_credential_test.cpp @@ -30,7 +30,6 @@ using Azure::Core::Credentials::TokenCredentialOptions; using Azure::Core::Http::HttpMethod; using Azure::Core::Http::HttpStatusCode; using Azure::Identity::ManagedIdentityCredential; -using Azure::Identity::ResourceIdentifier; using Azure::Identity::Test::_detail::CredentialTestHelper; TEST(ManagedIdentityCredential, GetCredentialName) @@ -241,96 +240,6 @@ TEST(ManagedIdentityCredential, AppServiceV2019ClientId) EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); } -TEST(ManagedIdentityCredential, AppServiceV2019ResourceId) -{ - auto const actual = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", "https://microsoft.com/"}, - {"MSI_SECRET", "CLIENTSECRET1"}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, - {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET2"}, - {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, - }); - - return std::make_unique( - ResourceIdentifier("abcdef01-2345-6789-9876-543210fedcba"), options); - }, - {{"https://azure.com/.default"}, {"https://outlook.com/.default"}, {}}, - std::vector{ - "{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}", - "{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}", - "{\"expires_in\":9999, \"access_token\":\"ACCESSTOKEN3\"}"}); - - EXPECT_EQ(actual.Requests.size(), 3U); - EXPECT_EQ(actual.Responses.size(), 3U); - - auto const& request0 = actual.Requests.at(0); - auto const& request1 = actual.Requests.at(1); - auto const& request2 = actual.Requests.at(2); - - auto const& response0 = actual.Responses.at(0); - auto const& response1 = actual.Responses.at(1); - auto const& response2 = actual.Responses.at(2); - - EXPECT_EQ(request0.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request1.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request2.HttpMethod, HttpMethod::Get); - - EXPECT_EQ( - request0.AbsoluteUrl, - "https://visualstudio.com" - "?api-version=2019-08-01" - "&mi_res_id=abcdef01-2345-6789-9876-543210fedcba" - "&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line - - EXPECT_EQ( - request1.AbsoluteUrl, - "https://visualstudio.com" - "?api-version=2019-08-01" - "&mi_res_id=abcdef01-2345-6789-9876-543210fedcba" - "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line - - EXPECT_EQ( - request2.AbsoluteUrl, - "https://visualstudio.com" - "?api-version=2019-08-01" - "&mi_res_id=abcdef01-2345-6789-9876-543210fedcba"); - - EXPECT_TRUE(request0.Body.empty()); - EXPECT_TRUE(request1.Body.empty()); - EXPECT_TRUE(request2.Body.empty()); - - { - EXPECT_NE(request0.Headers.find("X-IDENTITY-HEADER"), request0.Headers.end()); - EXPECT_EQ(request0.Headers.at("X-IDENTITY-HEADER"), "CLIENTSECRET2"); - - EXPECT_NE(request1.Headers.find("X-IDENTITY-HEADER"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("X-IDENTITY-HEADER"), "CLIENTSECRET2"); - - EXPECT_NE(request2.Headers.find("X-IDENTITY-HEADER"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("X-IDENTITY-HEADER"), "CLIENTSECRET2"); - } - - EXPECT_EQ(response0.AccessToken.Token, "ACCESSTOKEN1"); - EXPECT_EQ(response1.AccessToken.Token, "ACCESSTOKEN2"); - EXPECT_EQ(response2.AccessToken.Token, "ACCESSTOKEN3"); - - using namespace std::chrono_literals; - EXPECT_GE(response0.AccessToken.ExpiresOn, response0.EarliestExpiration + 3600s); - EXPECT_LE(response0.AccessToken.ExpiresOn, response0.LatestExpiration + 3600s); - - EXPECT_GE(response1.AccessToken.ExpiresOn, response1.EarliestExpiration + 3600s); - EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 3600s); - - EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 4999s); - EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); -} - TEST(ManagedIdentityCredential, AppServiceV2019InvalidUrl) { using Azure::Core::Diagnostics::Logger; @@ -613,96 +522,6 @@ TEST(ManagedIdentityCredential, AppServiceV2017ClientId) EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); } -TEST(ManagedIdentityCredential, AppServiceV2017ResourceId) -{ - auto const actual = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", "https://microsoft.com/"}, - {"MSI_SECRET", "CLIENTSECRET1"}, - {"IDENTITY_ENDPOINT", ""}, - {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET2"}, - {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, - }); - - return std::make_unique( - ResourceIdentifier("abcdef01-2345-6789-9876-543210fedcba"), options); - }, - {{"https://azure.com/.default"}, {"https://outlook.com/.default"}, {}}, - std::vector{ - "{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}", - "{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}", - "{\"expires_in\":9999, \"access_token\":\"ACCESSTOKEN3\"}"}); - - EXPECT_EQ(actual.Requests.size(), 3U); - EXPECT_EQ(actual.Responses.size(), 3U); - - auto const& request0 = actual.Requests.at(0); - auto const& request1 = actual.Requests.at(1); - auto const& request2 = actual.Requests.at(2); - - auto const& response0 = actual.Responses.at(0); - auto const& response1 = actual.Responses.at(1); - auto const& response2 = actual.Responses.at(2); - - EXPECT_EQ(request0.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request1.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request2.HttpMethod, HttpMethod::Get); - - EXPECT_EQ( - request0.AbsoluteUrl, - "https://microsoft.com" - "?api-version=2017-09-01" - "&mi_res_id=abcdef01-2345-6789-9876-543210fedcba" - "&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line - - EXPECT_EQ( - request1.AbsoluteUrl, - "https://microsoft.com" - "?api-version=2017-09-01" - "&mi_res_id=abcdef01-2345-6789-9876-543210fedcba" - "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line - - EXPECT_EQ( - request2.AbsoluteUrl, - "https://microsoft.com" - "?api-version=2017-09-01" - "&mi_res_id=abcdef01-2345-6789-9876-543210fedcba"); - - EXPECT_TRUE(request0.Body.empty()); - EXPECT_TRUE(request1.Body.empty()); - EXPECT_TRUE(request2.Body.empty()); - - { - EXPECT_NE(request0.Headers.find("secret"), request0.Headers.end()); - EXPECT_EQ(request0.Headers.at("secret"), "CLIENTSECRET1"); - - EXPECT_NE(request1.Headers.find("secret"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("secret"), "CLIENTSECRET1"); - - EXPECT_NE(request2.Headers.find("secret"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("secret"), "CLIENTSECRET1"); - } - - EXPECT_EQ(response0.AccessToken.Token, "ACCESSTOKEN1"); - EXPECT_EQ(response1.AccessToken.Token, "ACCESSTOKEN2"); - EXPECT_EQ(response2.AccessToken.Token, "ACCESSTOKEN3"); - - using namespace std::chrono_literals; - EXPECT_GE(response0.AccessToken.ExpiresOn, response0.EarliestExpiration + 3600s); - EXPECT_LE(response0.AccessToken.ExpiresOn, response0.LatestExpiration + 3600s); - - EXPECT_GE(response1.AccessToken.ExpiresOn, response1.EarliestExpiration + 3600s); - EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 3600s); - - EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 4999s); - EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); -} - TEST(ManagedIdentityCredential, AppServiceV2017InvalidUrl) { using Azure::Core::Credentials::AccessToken; @@ -951,84 +770,6 @@ TEST(ManagedIdentityCredential, CloudShellClientId) EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); } -TEST(ManagedIdentityCredential, CloudShellResourceId) -{ - auto const actual = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", "https://microsoft.com/"}, - {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, - {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", ""}, - {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, - }); - - return std::make_unique( - ResourceIdentifier("abcdef01-2345-6789-9876-543210fedcba"), options); - }, - {{"https://azure.com/.default"}, {"https://outlook.com/.default"}, {}}, - std::vector{ - "{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}", - "{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}", - "{\"expires_in\":9999, \"access_token\":\"ACCESSTOKEN3\"}"}); - - EXPECT_EQ(actual.Requests.size(), 3U); - EXPECT_EQ(actual.Responses.size(), 3U); - - auto const& request0 = actual.Requests.at(0); - auto const& request1 = actual.Requests.at(1); - auto const& request2 = actual.Requests.at(2); - - auto const& response0 = actual.Responses.at(0); - auto const& response1 = actual.Responses.at(1); - auto const& response2 = actual.Responses.at(2); - - EXPECT_EQ(request0.HttpMethod, HttpMethod::Post); - EXPECT_EQ(request1.HttpMethod, HttpMethod::Post); - EXPECT_EQ(request2.HttpMethod, HttpMethod::Post); - - EXPECT_EQ(request0.AbsoluteUrl, "https://microsoft.com"); - EXPECT_EQ(request1.AbsoluteUrl, "https://microsoft.com"); - EXPECT_EQ(request2.AbsoluteUrl, "https://microsoft.com"); - - EXPECT_EQ(request0.Body, - "resource=https%3A%2F%2Fazure.com"); // cspell:disable-line - - EXPECT_EQ(request1.Body, - "resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line - - EXPECT_EQ(request2.Body, ""); - - { - EXPECT_NE(request0.Headers.find("Metadata"), request0.Headers.end()); - EXPECT_EQ(request0.Headers.at("Metadata"), "true"); - - EXPECT_NE(request1.Headers.find("Metadata"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("Metadata"), "true"); - - EXPECT_NE(request2.Headers.find("Metadata"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("Metadata"), "true"); - } - - EXPECT_EQ(response0.AccessToken.Token, "ACCESSTOKEN1"); - EXPECT_EQ(response1.AccessToken.Token, "ACCESSTOKEN2"); - EXPECT_EQ(response2.AccessToken.Token, "ACCESSTOKEN3"); - - using namespace std::chrono_literals; - EXPECT_GE(response0.AccessToken.ExpiresOn, response0.EarliestExpiration + 3600s); - EXPECT_LE(response0.AccessToken.ExpiresOn, response0.LatestExpiration + 3600s); - - EXPECT_GE(response1.AccessToken.ExpiresOn, response1.EarliestExpiration + 3600s); - EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 3600s); - - EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 4999s); - EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); -} - TEST(ManagedIdentityCredential, CloudShellInvalidUrl) { using Azure::Core::Credentials::AccessToken; @@ -1341,37 +1082,6 @@ TEST(ManagedIdentityCredential, AzureArcClientId) {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"})); } -TEST(ManagedIdentityCredential, AzureArcResourceId) -{ - using Azure::Core::Credentials::AccessToken; - using Azure::Core::Credentials::AuthenticationException; - - static_cast(CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", ""}, - {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, - {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", ""}, - {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, - }); - - std::unique_ptr azureArcManagedIdentityCredential; - EXPECT_THROW( - azureArcManagedIdentityCredential = std::make_unique( - ResourceIdentifier("abcdef01-2345-6789-9876-543210fedcba"), options), - AuthenticationException); - - return azureArcManagedIdentityCredential; - }, - {}, - {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"})); -} - TEST(ManagedIdentityCredential, AzureArcAuthHeaderMissing) { using Azure::Core::Credentials::AccessToken; @@ -2045,96 +1755,6 @@ TEST(ManagedIdentityCredential, ImdsClientId) EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); } -TEST(ManagedIdentityCredential, ImdsResourceId) -{ - auto const actual = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", ""}, - {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", ""}, - {"IMDS_ENDPOINT", ""}, - {"IDENTITY_HEADER", ""}, - {"IDENTITY_SERVER_THUMBPRINT", ""}, - }); - - return std::make_unique( - ResourceIdentifier("abcdef01-2345-6789-9876-543210fedcba"), options); - }, - {{"https://azure.com/.default"}, {"https://outlook.com/.default"}, {}}, - std::vector{ - "{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}", - "{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}", - "{\"expires_in\":9999, \"access_token\":\"ACCESSTOKEN3\"}"}); - - EXPECT_EQ(actual.Requests.size(), 3U); - EXPECT_EQ(actual.Responses.size(), 3U); - - auto const& request0 = actual.Requests.at(0); - auto const& request1 = actual.Requests.at(1); - auto const& request2 = actual.Requests.at(2); - - auto const& response0 = actual.Responses.at(0); - auto const& response1 = actual.Responses.at(1); - auto const& response2 = actual.Responses.at(2); - - EXPECT_EQ(request0.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request1.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request2.HttpMethod, HttpMethod::Get); - - EXPECT_EQ( - request0.AbsoluteUrl, - "http://169.254.169.254/metadata/identity/oauth2/token" - "?api-version=2018-02-01" - "&msi_res_id=abcdef01-2345-6789-9876-543210fedcba" - "&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line - - EXPECT_EQ( - request1.AbsoluteUrl, - "http://169.254.169.254/metadata/identity/oauth2/token" - "?api-version=2018-02-01" - "&msi_res_id=abcdef01-2345-6789-9876-543210fedcba" - "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line - - EXPECT_EQ( - request2.AbsoluteUrl, - "http://169.254.169.254/metadata/identity/oauth2/token" - "?api-version=2018-02-01" - "&msi_res_id=abcdef01-2345-6789-9876-543210fedcba"); - - EXPECT_TRUE(request0.Body.empty()); - EXPECT_TRUE(request1.Body.empty()); - EXPECT_TRUE(request2.Body.empty()); - - { - EXPECT_NE(request0.Headers.find("Metadata"), request0.Headers.end()); - EXPECT_EQ(request0.Headers.at("Metadata"), "true"); - - EXPECT_NE(request1.Headers.find("Metadata"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("Metadata"), "true"); - - EXPECT_NE(request2.Headers.find("Metadata"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("Metadata"), "true"); - } - - EXPECT_EQ(response0.AccessToken.Token, "ACCESSTOKEN1"); - EXPECT_EQ(response1.AccessToken.Token, "ACCESSTOKEN2"); - EXPECT_EQ(response2.AccessToken.Token, "ACCESSTOKEN3"); - - using namespace std::chrono_literals; - EXPECT_GE(response0.AccessToken.ExpiresOn, response0.EarliestExpiration + 3600s); - EXPECT_LE(response0.AccessToken.ExpiresOn, response0.LatestExpiration + 3600s); - - EXPECT_GE(response1.AccessToken.ExpiresOn, response1.EarliestExpiration + 3600s); - EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 3600s); - - EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 4999s); - EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 4999s); -} - TEST(ManagedIdentityCredential, ImdsCreation) { auto const actual1 = CredentialTestHelper::SimulateTokenRequest( @@ -2227,127 +1847,3 @@ TEST(ManagedIdentityCredential, ImdsCreation) EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 3600s); EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 3600s); } - -TEST(ManagedIdentityCredential, ImdsCustomHost) -{ - auto const actual1 = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", ""}, - {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, - {"IMDS_ENDPOINT", ""}, - {"IDENTITY_HEADER", ""}, - {"IDENTITY_SERVER_THUMBPRINT", ""}, - {"AZURE_IMDS_CUSTOM_AUTHORITY_HOST", ""}, - }); - - return std::make_unique( - "fedcba98-7654-3210-0123-456789abcdef", options); - }, - {{"https://azure.com/.default"}}, - {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"}); - - auto const actual2 = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", ""}, - {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", ""}, - {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", ""}, - {"IDENTITY_SERVER_THUMBPRINT", ""}, - {"AZURE_IMDS_CUSTOM_AUTHORITY_HOST", "https://custom.imds.endpoint/"}, - }); - - return std::make_unique( - "01234567-89ab-cdef-fedc-ba9876543210", options); - }, - {{"https://outlook.com/.default"}}, - {"{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}"}); - - auto const actual3 = CredentialTestHelper::SimulateTokenRequest( - [](auto transport) { - TokenCredentialOptions options; - options.Transport.Transport = transport; - - CredentialTestHelper::EnvironmentOverride const env({ - {"MSI_ENDPOINT", ""}, - {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", ""}, - {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", ""}, - {"IDENTITY_SERVER_THUMBPRINT", ""}, - {"AZURE_IMDS_CUSTOM_AUTHORITY_HOST", "http://localhost:59202"}, - }); - - return std::make_unique( - "01234567-89ab-cdef-fedc-ba9876543210", options); - }, - {{"https://outlook.com/.default"}}, - {"{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}"}); - - EXPECT_EQ(actual1.Requests.size(), 1U); - EXPECT_EQ(actual1.Responses.size(), 1U); - - EXPECT_EQ(actual2.Requests.size(), 1U); - EXPECT_EQ(actual2.Responses.size(), 1U); - - auto const& request1 = actual1.Requests.at(0); - auto const& response1 = actual1.Responses.at(0); - - auto const& request2 = actual2.Requests.at(0); - auto const& response2 = actual2.Responses.at(0); - - EXPECT_EQ(request1.HttpMethod, HttpMethod::Get); - EXPECT_EQ(request2.HttpMethod, HttpMethod::Get); - - EXPECT_EQ( - request1.AbsoluteUrl, - "http://169.254.169.254/metadata/identity/oauth2/token" - "?api-version=2018-02-01" - "&client_id=fedcba98-7654-3210-0123-456789abcdef" - "&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line - - EXPECT_EQ( - request2.AbsoluteUrl, - "https://custom.imds.endpoint/metadata/identity/oauth2/token" - "?api-version=2018-02-01" - "&client_id=01234567-89ab-cdef-fedc-ba9876543210" - "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line - - auto const& request3 = actual3.Requests.at(0); - EXPECT_EQ( - request3.AbsoluteUrl, - "http://localhost:59202/metadata/identity/oauth2/token" - "?api-version=2018-02-01" - "&client_id=01234567-89ab-cdef-fedc-ba9876543210" - "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line - - EXPECT_TRUE(request1.Body.empty()); - EXPECT_TRUE(request2.Body.empty()); - - { - EXPECT_NE(request1.Headers.find("Metadata"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("Metadata"), "true"); - - EXPECT_NE(request2.Headers.find("Metadata"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("Metadata"), "true"); - } - - EXPECT_EQ(response1.AccessToken.Token, "ACCESSTOKEN1"); - EXPECT_EQ(response2.AccessToken.Token, "ACCESSTOKEN2"); - - using namespace std::chrono_literals; - EXPECT_GE(response1.AccessToken.ExpiresOn, response1.EarliestExpiration + 3600s); - EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 3600s); - - EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 3600s); - EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 3600s); -} diff --git a/sdk/identity/azure-identity/test/ut/resource_identifier_test.cpp b/sdk/identity/azure-identity/test/ut/resource_identifier_test.cpp deleted file mode 100644 index f9bf8a280..000000000 --- a/sdk/identity/azure-identity/test/ut/resource_identifier_test.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#include "azure/identity/managed_identity_credential.hpp" - -#include - -#include - -using namespace Azure::Identity; - -TEST(ResourceIdentifier, Basic) -{ - std::string resourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg/" - "providers/Compute/virtualMachines/vm-name"; - ResourceIdentifier resourceIdentifier(resourceId); - EXPECT_EQ(resourceIdentifier.ToString(), resourceId); -}