Skip to content

Commit

Permalink
ManagedIdentityCredential: Add support for AppServiceV2019 (#3734)
Browse files Browse the repository at this point in the history
* ManagedIdentityCredential: Add support for AppServiceV2019

* Attempt to create 2019 before 2017

* Changelog update

Co-authored-by: Anton Kolesnyk <[email protected]>
  • Loading branch information
antkmsft and antkmsft authored Jun 20, 2022
1 parent fd40343 commit 5f575c3
Show file tree
Hide file tree
Showing 5 changed files with 376 additions and 53 deletions.
2 changes: 2 additions & 0 deletions sdk/identity/azure-identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Features Added

- Added Azure App Service API version `2019-08-01` support for `ManagedIdentityCredential`.

### Breaking Changes

### Bugs Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ std::unique_ptr<_detail::ManagedIdentitySource> CreateManagedIdentitySource(
using namespace Azure::Identity::_detail;
static std::unique_ptr<ManagedIdentitySource> (*managedIdentitySourceCreate[])(
std::string const& clientId, TokenCredentialOptions const& options)
= {AppServiceManagedIdentitySource::Create,
= {AppServiceV2019ManagedIdentitySource::Create,
AppServiceV2017ManagedIdentitySource::Create,
CloudShellManagedIdentitySource::Create,
AzureArcManagedIdentitySource::Create,
ImdsManagedIdentitySource::Create};
Expand Down
41 changes: 31 additions & 10 deletions sdk/identity/azure-identity/src/managed_identity_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,41 +35,46 @@ Azure::Core::Url ManagedIdentitySource::ParseEndpointUrl(
std::string("The environment variable ") + envVarName + " contains an invalid URL.");
}

template <typename T>
std::unique_ptr<ManagedIdentitySource> 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<ManagedIdentitySource>(new AppServiceManagedIdentitySource(
clientId, options, ParseEndpointUrl(msiEndpoint, EndpointVarName), msiSecret));
: std::unique_ptr<ManagedIdentitySource>(
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))
{
{
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(
Expand All @@ -90,6 +95,22 @@ Azure::Core::Credentials::AccessToken AppServiceManagedIdentitySource::GetToken(
});
}

std::unique_ptr<ManagedIdentitySource> AppServiceV2017ManagedIdentitySource::Create(
std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options)
{
return AppServiceManagedIdentitySource::Create<AppServiceV2017ManagedIdentitySource>(
clientId, options, "MSI_ENDPOINT", "MSI_SECRET");
}

std::unique_ptr<ManagedIdentitySource> AppServiceV2019ManagedIdentitySource::Create(
std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options)
{
return AppServiceManagedIdentitySource::Create<AppServiceV2019ManagedIdentitySource>(
clientId, options, "IDENTITY_ENDPOINT", "IDENTITY_HEADER");
}

std::unique_ptr<ManagedIdentitySource> CloudShellManagedIdentitySource::Create(
std::string const& clientId,
Azure::Core::Credentials::TokenCredentialOptions const& options)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
static std::unique_ptr<ManagedIdentitySource> 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<ManagedIdentitySource> 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<ManagedIdentitySource> Create(
std::string const& clientId,
Core::Credentials::TokenCredentialOptions const& options);
};

class CloudShellManagedIdentitySource final : public ManagedIdentitySource {
Expand Down
Loading

0 comments on commit 5f575c3

Please sign in to comment.