diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index acaf2388eb..1758a39118 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features Added +- Added Azure App Service API version `2019-08-01` support for `ManagedIdentityCredential`. + ### Breaking Changes ### Bugs Fixed diff --git a/sdk/identity/azure-identity/src/managed_identity_credential.cpp b/sdk/identity/azure-identity/src/managed_identity_credential.cpp index 0d0c9737b6..209dfb8b4f 100644 --- a/sdk/identity/azure-identity/src/managed_identity_credential.cpp +++ b/sdk/identity/azure-identity/src/managed_identity_credential.cpp @@ -15,7 +15,8 @@ std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource( using namespace Azure::Identity::_detail; static std::unique_ptr (*managedIdentitySourceCreate[])( std::string const& clientId, TokenCredentialOptions const& options) - = {AppServiceManagedIdentitySource::Create, + = {AppServiceV2019ManagedIdentitySource::Create, + AppServiceV2017ManagedIdentitySource::Create, CloudShellManagedIdentitySource::Create, AzureArcManagedIdentitySource::Create, ImdsManagedIdentitySource::Create}; diff --git a/sdk/identity/azure-identity/src/managed_identity_source.cpp b/sdk/identity/azure-identity/src/managed_identity_source.cpp index ba0164b9da..56fbf51273 100644 --- a/sdk/identity/azure-identity/src/managed_identity_source.cpp +++ b/sdk/identity/azure-identity/src/managed_identity_source.cpp @@ -35,25 +35,30 @@ Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl( std::string("The environment variable ") + envVarName + " contains an invalid URL."); } +template std::unique_ptr AppServiceManagedIdentitySource::Create( std::string const& clientId, - Azure::Core::Credentials::TokenCredentialOptions const& options) + Azure::Core::Credentials::TokenCredentialOptions const& options, + const char* endpointVarName, + const char* secretVarName) { - constexpr auto EndpointVarName = "MSI_ENDPOINT"; - auto msiEndpoint = Environment::GetVariable(EndpointVarName); - auto msiSecret = Environment::GetVariable("MSI_SECRET"); + auto msiEndpoint = Environment::GetVariable(endpointVarName); + auto msiSecret = Environment::GetVariable(secretVarName); return (msiEndpoint.empty() || msiSecret.empty()) ? nullptr - : std::unique_ptr(new AppServiceManagedIdentitySource( - clientId, options, ParseEndpointUrl(msiEndpoint, EndpointVarName), msiSecret)); + : std::unique_ptr( + new T(clientId, options, ParseEndpointUrl(msiEndpoint, endpointVarName), msiSecret)); } AppServiceManagedIdentitySource::AppServiceManagedIdentitySource( std::string const& clientId, Azure::Core::Credentials::TokenCredentialOptions const& options, Azure::Core::Url endpointUrl, - std::string const& secret) + std::string const& secret, + std::string const& apiVersion, + std::string const& secretHeaderName, + std::string const& clientIdHeaderName) : ManagedIdentitySource(options), m_request(Azure::Core::Http::HttpMethod::Get, std::move(endpointUrl)) { @@ -61,15 +66,15 @@ AppServiceManagedIdentitySource::AppServiceManagedIdentitySource( using Azure::Core::Url; auto& url = m_request.GetUrl(); - url.AppendQueryParameter("api-version", "2017-09-01"); + url.AppendQueryParameter("api-version", apiVersion); if (!clientId.empty()) { - url.AppendQueryParameter("clientid", clientId); + url.AppendQueryParameter(clientIdHeaderName, clientId); } } - m_request.SetHeader("secret", secret); + m_request.SetHeader(secretHeaderName, secret); } Azure::Core::Credentials::AccessToken AppServiceManagedIdentitySource::GetToken( @@ -90,6 +95,22 @@ Azure::Core::Credentials::AccessToken AppServiceManagedIdentitySource::GetToken( }); } +std::unique_ptr AppServiceV2017ManagedIdentitySource::Create( + std::string const& clientId, + Core::Credentials::TokenCredentialOptions const& options) +{ + return AppServiceManagedIdentitySource::Create( + clientId, options, "MSI_ENDPOINT", "MSI_SECRET"); +} + +std::unique_ptr AppServiceV2019ManagedIdentitySource::Create( + std::string const& clientId, + Core::Credentials::TokenCredentialOptions const& options) +{ + return AppServiceManagedIdentitySource::Create( + clientId, options, "IDENTITY_ENDPOINT", "IDENTITY_HEADER"); +} + std::unique_ptr CloudShellManagedIdentitySource::Create( std::string const& clientId, Azure::Core::Credentials::TokenCredentialOptions const& options) 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 d603d15fa3..40d66fc589 100644 --- a/sdk/identity/azure-identity/src/private/managed_identity_source.hpp +++ b/sdk/identity/azure-identity/src/private/managed_identity_source.hpp @@ -28,24 +28,83 @@ namespace Azure { namespace Identity { namespace _detail { } }; - class AppServiceManagedIdentitySource final : public ManagedIdentitySource { + class AppServiceManagedIdentitySource : public ManagedIdentitySource { private: Core::Http::Request m_request; + protected: explicit AppServiceManagedIdentitySource( std::string const& clientId, Core::Credentials::TokenCredentialOptions const& options, Core::Url endpointUrl, - std::string const& secret); + std::string const& secret, + std::string const& apiVersion, + std::string const& secretHeaderName, + std::string const& clientIdHeaderName); - public: + template static std::unique_ptr Create( std::string const& clientId, - Core::Credentials::TokenCredentialOptions const& options); + Core::Credentials::TokenCredentialOptions const& options, + const char* endpointVarName, + const char* secretVarName); + public: Core::Credentials::AccessToken GetToken( Core::Credentials::TokenRequestContext const& tokenRequestContext, - Core::Context const& context) const override; + Core::Context const& context) const override final; + }; + + class AppServiceV2017ManagedIdentitySource final : public AppServiceManagedIdentitySource { + friend class AppServiceManagedIdentitySource; + + private: + explicit AppServiceV2017ManagedIdentitySource( + std::string const& clientId, + Core::Credentials::TokenCredentialOptions const& options, + Core::Url endpointUrl, + std::string const& secret) + : AppServiceManagedIdentitySource( + clientId, + options, + endpointUrl, + secret, + "2017-09-01", + "secret", + "clientid") + { + } + + public: + static std::unique_ptr Create( + std::string const& clientId, + Core::Credentials::TokenCredentialOptions const& options); + }; + + class AppServiceV2019ManagedIdentitySource final : public AppServiceManagedIdentitySource { + friend class AppServiceManagedIdentitySource; + + private: + explicit AppServiceV2019ManagedIdentitySource( + std::string const& clientId, + Core::Credentials::TokenCredentialOptions const& options, + Core::Url endpointUrl, + std::string const& secret) + : AppServiceManagedIdentitySource( + clientId, + options, + endpointUrl, + secret, + "2019-08-01", + "X-IDENTITY-HEADER", + "client_id") + { + } + + public: + static std::unique_ptr Create( + std::string const& clientId, + Core::Credentials::TokenCredentialOptions const& options); }; class CloudShellManagedIdentitySource final : public ManagedIdentitySource { 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 0166c46a48..27f7d5b80b 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 @@ -15,7 +15,7 @@ using Azure::Core::Http::HttpStatusCode; using Azure::Identity::ManagedIdentityCredential; using Azure::Identity::Test::_detail::CredentialTestHelper; -TEST(ManagedIdentityCredential, AppService) +TEST(ManagedIdentityCredential, AppServiceV2019) { auto const actual = CredentialTestHelper::SimulateTokenRequest( [](auto transport) { @@ -24,10 +24,250 @@ TEST(ManagedIdentityCredential, AppService) CredentialTestHelper::EnvironmentOverride const env({ {"MSI_ENDPOINT", "https://microsoft.com/"}, - {"MSI_SECRET", "CLIENTSECRET"}, + {"MSI_SECRET", "CLIENTSECRET1"}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", "CLIENTSECRET2"}, + {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, + }); + + return std::make_unique(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" + "&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line + + EXPECT_EQ( + request1.AbsoluteUrl, + "https://visualstudio.com" + "?api-version=2019-08-01" + "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line + + EXPECT_EQ( + request2.AbsoluteUrl, + "https://visualstudio.com" + "?api-version=2019-08-01"); + + 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 + 7200s); + EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 7200s); + + EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 9999s); + EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 9999s); +} + +TEST(ManagedIdentityCredential, AppServiceV2019ClientId) +{ + 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( + "fedcba98-7654-3210-0123-456789abcdef", 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" + "&client_id=fedcba98-7654-3210-0123-456789abcdef" + "&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line + + EXPECT_EQ( + request1.AbsoluteUrl, + "https://visualstudio.com" + "?api-version=2019-08-01" + "&client_id=fedcba98-7654-3210-0123-456789abcdef" + "&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line + + EXPECT_EQ( + request2.AbsoluteUrl, + "https://visualstudio.com" + "?api-version=2019-08-01" + "&client_id=fedcba98-7654-3210-0123-456789abcdef"); + + 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 + 7200s); + EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 7200s); + + EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 9999s); + EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 9999s); +} + +TEST(ManagedIdentityCredential, AppServiceV2019InvalidUrl) +{ + using Azure::Core::Credentials::AccessToken; + using Azure::Core::Credentials::AuthenticationException; + + using Azure::Core::Credentials::AuthenticationException; + static_cast(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:INVALID/"}, + {"IMDS_ENDPOINT", "https://xbox.com/"}, + {"IDENTITY_HEADER", "CLIENTSECRET2"}, + {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, + }); + + std::unique_ptr appServiceV2019ManagedIdentityCredential; + EXPECT_THROW( + appServiceV2019ManagedIdentityCredential + = std::make_unique(options), + AuthenticationException); + + return appServiceV2019ManagedIdentityCredential; + }, + {}, + {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"})); +} + +TEST(ManagedIdentityCredential, AppServiceV2019UnsupportedUrl) +{ + using Azure::Core::Credentials::AccessToken; + using Azure::Core::Credentials::AuthenticationException; + + using Azure::Core::Credentials::AuthenticationException; + static_cast(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:65536/"}, + {"IMDS_ENDPOINT", "https://xbox.com/"}, + {"IDENTITY_HEADER", "CLIENTSECRET2"}, + {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, + }); + + std::unique_ptr appServiceV2019ManagedIdentityCredential; + EXPECT_THROW( + appServiceV2019ManagedIdentityCredential + = std::make_unique(options), + AuthenticationException); + + return appServiceV2019ManagedIdentityCredential; + }, + {}, + {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"})); +} + +TEST(ManagedIdentityCredential, AppServiceV2017) +{ + 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", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -77,13 +317,13 @@ TEST(ManagedIdentityCredential, AppService) { EXPECT_NE(request0.Headers.find("secret"), request0.Headers.end()); - EXPECT_EQ(request0.Headers.at("secret"), "CLIENTSECRET"); + EXPECT_EQ(request0.Headers.at("secret"), "CLIENTSECRET1"); EXPECT_NE(request1.Headers.find("secret"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("secret"), "CLIENTSECRET"); + EXPECT_EQ(request1.Headers.at("secret"), "CLIENTSECRET1"); EXPECT_NE(request2.Headers.find("secret"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("secret"), "CLIENTSECRET"); + EXPECT_EQ(request2.Headers.at("secret"), "CLIENTSECRET1"); } EXPECT_EQ(response0.AccessToken.Token, "ACCESSTOKEN1"); @@ -101,7 +341,7 @@ TEST(ManagedIdentityCredential, AppService) EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 9999s); } -TEST(ManagedIdentityCredential, AppServiceClientId) +TEST(ManagedIdentityCredential, AppServiceV2017ClientId) { auto const actual = CredentialTestHelper::SimulateTokenRequest( [](auto transport) { @@ -110,10 +350,10 @@ TEST(ManagedIdentityCredential, AppServiceClientId) CredentialTestHelper::EnvironmentOverride const env({ {"MSI_ENDPOINT", "https://microsoft.com/"}, - {"MSI_SECRET", "CLIENTSECRET"}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, + {"MSI_SECRET", "CLIENTSECRET1"}, + {"IDENTITY_ENDPOINT", ""}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", "CLIENTSECRET2"}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -167,13 +407,13 @@ TEST(ManagedIdentityCredential, AppServiceClientId) { EXPECT_NE(request0.Headers.find("secret"), request0.Headers.end()); - EXPECT_EQ(request0.Headers.at("secret"), "CLIENTSECRET"); + EXPECT_EQ(request0.Headers.at("secret"), "CLIENTSECRET1"); EXPECT_NE(request1.Headers.find("secret"), request1.Headers.end()); - EXPECT_EQ(request1.Headers.at("secret"), "CLIENTSECRET"); + EXPECT_EQ(request1.Headers.at("secret"), "CLIENTSECRET1"); EXPECT_NE(request2.Headers.find("secret"), request2.Headers.end()); - EXPECT_EQ(request2.Headers.at("secret"), "CLIENTSECRET"); + EXPECT_EQ(request2.Headers.at("secret"), "CLIENTSECRET1"); } EXPECT_EQ(response0.AccessToken.Token, "ACCESSTOKEN1"); @@ -191,7 +431,7 @@ TEST(ManagedIdentityCredential, AppServiceClientId) EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 9999s); } -TEST(ManagedIdentityCredential, AppServiceInvalidUrl) +TEST(ManagedIdentityCredential, AppServiceV2017InvalidUrl) { using Azure::Core::Credentials::AccessToken; using Azure::Core::Credentials::AuthenticationException; @@ -204,26 +444,26 @@ TEST(ManagedIdentityCredential, AppServiceInvalidUrl) CredentialTestHelper::EnvironmentOverride const env({ {"MSI_ENDPOINT", "https://microsoft.com:INVALID/"}, - {"MSI_SECRET", "CLIENTSECRET"}, + {"MSI_SECRET", "CLIENTSECRET1"}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); - std::unique_ptr appServiceManagedIdentityCredential; + std::unique_ptr appServiceV2017ManagedIdentityCredential; EXPECT_THROW( - appServiceManagedIdentityCredential + appServiceV2017ManagedIdentityCredential = std::make_unique(options), AuthenticationException); - return appServiceManagedIdentityCredential; + return appServiceV2017ManagedIdentityCredential; }, {}, {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"})); } -TEST(ManagedIdentityCredential, AppServiceUnsupportedUrl) +TEST(ManagedIdentityCredential, AppServiceV2017UnsupportedUrl) { using Azure::Core::Credentials::AccessToken; using Azure::Core::Credentials::AuthenticationException; @@ -236,20 +476,20 @@ TEST(ManagedIdentityCredential, AppServiceUnsupportedUrl) CredentialTestHelper::EnvironmentOverride const env({ {"MSI_ENDPOINT", "https://microsoft.com:65536/"}, - {"MSI_SECRET", "CLIENTSECRET"}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, + {"MSI_SECRET", "CLIENTSECRET1"}, + {"IDENTITY_ENDPOINT", ""}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", "CLIENTSECRET2"}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); - std::unique_ptr appServiceManagedIdentityCredential; + std::unique_ptr appServiceV2017ManagedIdentityCredential; EXPECT_THROW( - appServiceManagedIdentityCredential + appServiceV2017ManagedIdentityCredential = std::make_unique(options), AuthenticationException); - return appServiceManagedIdentityCredential; + return appServiceV2017ManagedIdentityCredential; }, {}, {"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"})); @@ -265,9 +505,9 @@ TEST(ManagedIdentityCredential, CloudShell) CredentialTestHelper::EnvironmentOverride const env({ {"MSI_ENDPOINT", "https://microsoft.com/"}, {"MSI_SECRET", ""}, - {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, + {"IDENTITY_ENDPOINT", ""}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", "SECRET2"}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -340,7 +580,7 @@ TEST(ManagedIdentityCredential, CloudShellClientId) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -423,7 +663,7 @@ TEST(ManagedIdentityCredential, CloudShellInvalidUrl) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -472,7 +712,7 @@ TEST(ManagedIdentityCredential, AzureArc) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -606,7 +846,7 @@ TEST(ManagedIdentityCredential, AzureArcClientId) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -637,7 +877,7 @@ TEST(ManagedIdentityCredential, AzureArcAuthHeaderMissing) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -676,7 +916,7 @@ TEST(ManagedIdentityCredential, AzureArcUnexpectedHttpStatusCode) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -710,7 +950,7 @@ TEST(ManagedIdentityCredential, AzureArcAuthHeaderNoEquals) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -742,7 +982,7 @@ TEST(ManagedIdentityCredential, AzureArcAuthHeaderTwoEquals) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, }); @@ -774,7 +1014,7 @@ TEST(ManagedIdentityCredential, AzureArcInvalidUrl) {"MSI_SECRET", ""}, {"IDENTITY_ENDPOINT", "https://visualstudio.com:INVALID/"}, {"IMDS_ENDPOINT", "https://xbox.com/"}, - {"IDENTITY_HEADER", "CLIENTSECRET"}, + {"IDENTITY_HEADER", ""}, {"IDENTITY_SERVER_THUMBPRINT", "0123456789abcdef0123456789abcdef01234567"}, });