From cc78776bcb6e7ed9c65dc8b36a9e5a811e0e7e24 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com> Date: Thu, 13 Aug 2020 14:28:08 -0700 Subject: [PATCH] EnvironmentCredential with ClientSecretCredential support (#442) --- .../inc/credentials/credentials.hpp | 25 +++++-- .../src/credentials/credentials.cpp | 67 +++++++++++++++++++ 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/sdk/core/azure-core/inc/credentials/credentials.hpp b/sdk/core/azure-core/inc/credentials/credentials.hpp index d5da90286..7d47db66e 100644 --- a/sdk/core/azure-core/inc/credentials/credentials.hpp +++ b/sdk/core/azure-core/inc/credentials/credentials.hpp @@ -3,8 +3,10 @@ #pragma once -#include #include + +#include +#include #include #include #include @@ -23,9 +25,10 @@ namespace Azure { namespace Core { namespace Credentials { virtual AccessToken GetToken(Context const& context, std::vector const& scopes) const = 0; + virtual ~TokenCredential() = default; + protected: TokenCredential() {} - virtual ~TokenCredential(){}; private: TokenCredential(TokenCredential const&) = delete; @@ -36,10 +39,10 @@ namespace Azure { namespace Core { namespace Credentials { private: static std::string const g_aadGlobalAuthority; - std::string const m_tenantId; - std::string const m_clientId; - std::string const m_clientSecret; - std::string const m_authority; + std::string m_tenantId; + std::string m_clientId; + std::string m_clientSecret; + std::string m_authority; public: explicit ClientSecretCredential( @@ -61,4 +64,14 @@ namespace Azure { namespace Core { namespace Credentials { explicit AuthenticationException(std::string const& msg) : std::runtime_error(msg) {} }; + class EnvironmentCredential : public TokenCredential { + std::unique_ptr m_credentialImpl; + + public: + explicit EnvironmentCredential(); + + AccessToken GetToken(Context const& context, std::vector const& scopes) + const override; + }; + }}} // namespace Azure::Core::Credentials diff --git a/sdk/core/azure-core/src/credentials/credentials.cpp b/sdk/core/azure-core/src/credentials/credentials.cpp index 17611b2c8..5bc3a5afe 100644 --- a/sdk/core/azure-core/src/credentials/credentials.cpp +++ b/sdk/core/azure-core/src/credentials/credentials.cpp @@ -6,6 +6,8 @@ #include #include #include + +#include #include #include #include @@ -196,3 +198,68 @@ AccessToken Azure::Core::Credentials::ClientSecretCredential::GetToken( throw AuthenticationException("unknown error"); } } + +Azure::Core::Credentials::EnvironmentCredential::EnvironmentCredential() +{ +#ifdef _MSC_VER +#pragma warning(push) +// warning C4996: 'getenv': This function or variable may be unsafe. Consider using _dupenv_s +// instead. +#pragma warning(disable : 4996) +#endif + + auto tenantId = std::getenv("AZURE_TENANT_ID"); + auto clientId = std::getenv("AZURE_CLIENT_ID"); + + auto clientSecret = std::getenv("AZURE_CLIENT_SECRET"); + auto authority = std::getenv("AZURE_AUTHORITY_HOST"); + + // auto username = std::getenv("AZURE_USERNAME"); + // auto password = std::getenv("AZURE_PASSWORD"); + // + // auto clientCertificatePath = std::getenv("AZURE_CLIENT_CERTIFICATE_PATH"); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + if (tenantId != nullptr && clientId != nullptr) + { + if (clientSecret != nullptr) + { + if (authority != nullptr) + { + m_credentialImpl.reset( + new ClientSecretCredential(tenantId, clientId, clientSecret, authority)); + } + else + { + m_credentialImpl.reset(new ClientSecretCredential(tenantId, clientId, clientSecret)); + } + } + // TODO: These credential types are not implemented. Uncomment when implemented. + // else if (username != nullptr && password != nullptr) + //{ + // m_credentialImpl.reset( + // new UsernamePasswordCredential(username, password, tenantId, clientId)); + //} + // else if (clientCertificatePath != nullptr) + //{ + // m_credentialImpl.reset( + // new ClientCertificateCredential(tenantId, clientId, clientCertificatePath)); + //} + } +} + +AccessToken Azure::Core::Credentials::EnvironmentCredential::GetToken( + Context const& context, + std::vector const& scopes) const +{ + if (!m_credentialImpl) + { + throw AuthenticationException("EnvironmentCredential authentication unavailable. " + "Environment variables are not fully configured."); + } + + return m_credentialImpl->GetToken(context, scopes); +}