Implement Phase 3 features for DefaultAzureCredential (#6724)
* Implement Phase 3 features for DefaultAzureCredential * Forgotten change to update header * Clang-format * GCC fix * Change 'envVarName' string parameter to a boolean 'requireEnvVarValue' parameter * Rename EnvVarName to CredentialSpecifierEnvVarName and make it constexpr auto * requireEnvVarValue => requireCredentialSpecifierEnvVarValue * Clang-format * Update unit test name * Clang-format * Update CHANGELOG with new features and bug fixes --------- Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>
This commit is contained in:
parent
573fe95a0e
commit
11a2a38aa7
@ -12,6 +12,12 @@ namespace Azure { namespace Core { namespace _internal {
|
||||
~Environment() = delete;
|
||||
|
||||
public:
|
||||
static std::string GetVariable(const std::string& name) { return GetVariable(name.c_str()); }
|
||||
static void SetVariable(const std::string& name, const std::string& value)
|
||||
{
|
||||
SetVariable(name.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
static std::string GetVariable(const char* name);
|
||||
static void SetVariable(const char* name, const char* value);
|
||||
};
|
||||
|
||||
@ -38,11 +38,13 @@ namespace Azure { namespace Core { namespace _internal {
|
||||
return IsDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
static constexpr bool IsAlphaNumeric(char c) noexcept
|
||||
static constexpr bool IsAlpha(char c) noexcept
|
||||
{
|
||||
return IsDigit(c) || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
}
|
||||
|
||||
static constexpr bool IsAlphaNumeric(char c) noexcept { return IsDigit(c) || IsAlpha(c); }
|
||||
|
||||
static constexpr bool IsSpace(char c) noexcept { return c == ' ' || (c >= '\t' && c <= '\r'); }
|
||||
|
||||
static constexpr bool IsPrintable(char c) noexcept { return c >= ' ' && c <= '~'; }
|
||||
|
||||
@ -2,8 +2,11 @@
|
||||
|
||||
## 1.13.1 (2025-09-11)
|
||||
|
||||
### Bugs Fixed
|
||||
### Features Added
|
||||
|
||||
- Added a constructor overload for `DefaultAzureCredential` with a boolean parameter to indicate whether to throw an exception if `AZURE_TOKEN_CREDENTIALS` environment variable doesn't have a value.
|
||||
|
||||
### Bugs Fixed
|
||||
- Fixed IMDS token requests for managed identities, which were broken by an invalid URL path in 1.12.0-beta.1. (A community contribution, courtesy of _[chewi](https://github.com/chewi)_)
|
||||
|
||||
### Acknowledgments
|
||||
|
||||
@ -62,6 +62,19 @@ namespace Azure { namespace Identity {
|
||||
*/
|
||||
explicit DefaultAzureCredential(Core::Credentials::TokenCredentialOptions const& options);
|
||||
|
||||
/**
|
||||
* @brief Constructs `%DefaultAzureCredential`.
|
||||
*
|
||||
* @param requireCredentialSpecifierEnvVarValue Throw an exception if `AZURE_TOKEN_CREDENTIALS`
|
||||
* environment variable is not set.
|
||||
*
|
||||
* @param options Generic Token Credential Options.
|
||||
*
|
||||
*/
|
||||
explicit DefaultAzureCredential(
|
||||
bool requireCredentialSpecifierEnvVarValue,
|
||||
Core::Credentials::TokenCredentialOptions const& options = {});
|
||||
|
||||
/**
|
||||
* @brief Destructs `%DefaultAzureCredential`.
|
||||
*
|
||||
|
||||
@ -26,7 +26,18 @@ using Azure::Core::_internal::StringExtensions;
|
||||
using Azure::Core::Diagnostics::Logger;
|
||||
using Azure::Identity::_detail::IdentityLog;
|
||||
|
||||
namespace {
|
||||
constexpr auto CredentialSpecifierEnvVarName = "AZURE_TOKEN_CREDENTIALS";
|
||||
} // namespace
|
||||
|
||||
DefaultAzureCredential::DefaultAzureCredential(
|
||||
Core::Credentials::TokenCredentialOptions const& options)
|
||||
: DefaultAzureCredential(false, options)
|
||||
{
|
||||
}
|
||||
|
||||
DefaultAzureCredential::DefaultAzureCredential(
|
||||
bool requireCredentialSpecifierEnvVarValue,
|
||||
Core::Credentials::TokenCredentialOptions const& options)
|
||||
: TokenCredential("DefaultAzureCredential")
|
||||
{
|
||||
@ -77,10 +88,16 @@ DefaultAzureCredential::DefaultAzureCredential(
|
||||
[](auto options) { return std::make_shared<AzureCliCredential>(options); }},
|
||||
};
|
||||
|
||||
constexpr auto envVarName = "AZURE_TOKEN_CREDENTIALS";
|
||||
const auto envVarValue = Environment::GetVariable(envVarName);
|
||||
const auto envVarValue = Environment::GetVariable(CredentialSpecifierEnvVarName);
|
||||
const auto trimmedEnvVarValue = StringExtensions::Trim(envVarValue);
|
||||
|
||||
if (requireCredentialSpecifierEnvVarValue && trimmedEnvVarValue.empty())
|
||||
{
|
||||
throw AuthenticationException(
|
||||
GetCredentialName() + ": '" + CredentialSpecifierEnvVarName
|
||||
+ "' environment variable is empty.");
|
||||
}
|
||||
|
||||
bool specificCred = false;
|
||||
if (!trimmedEnvVarValue.empty())
|
||||
{
|
||||
@ -92,8 +109,8 @@ DefaultAzureCredential::DefaultAzureCredential(
|
||||
specificCred = true;
|
||||
IdentityLog::Write(
|
||||
IdentityLog::Level::Verbose,
|
||||
GetCredentialName() + ": '" + envVarName + "' environment variable is set to '"
|
||||
+ envVarValue
|
||||
GetCredentialName() + ": '" + CredentialSpecifierEnvVarName
|
||||
+ "' environment variable is set to '" + envVarValue
|
||||
+ "', therefore credential chain will only contain single credential: "
|
||||
+ cred.CredentialName + '.');
|
||||
credentialChain.emplace_back(cred.Create(options));
|
||||
@ -143,7 +160,8 @@ DefaultAzureCredential::DefaultAzureCredential(
|
||||
}
|
||||
}
|
||||
|
||||
const auto logMsg = GetCredentialName() + ": '" + envVarName + "' environment variable is "
|
||||
const auto logMsg = GetCredentialName() + ": '" + CredentialSpecifierEnvVarName
|
||||
+ "' environment variable is "
|
||||
+ (envVarValue.empty() ? "not set" : ("set to '" + envVarValue + "'"))
|
||||
+ ((devCredCount > 0)
|
||||
? (", therefore " + devCredNames + " will " + (isProd ? "NOT " : "")
|
||||
@ -177,10 +195,13 @@ DefaultAzureCredential::DefaultAzureCredential(
|
||||
}
|
||||
|
||||
throw AuthenticationException(
|
||||
GetCredentialName() + ": Invalid value '" + envVarValue + "' for the '" + envVarName
|
||||
GetCredentialName() + ": Invalid value '" + envVarValue + "' for the '"
|
||||
+ CredentialSpecifierEnvVarName
|
||||
+ "' environment variable. Allowed values are 'dev', 'prod'" + allowedCredNames
|
||||
+ " (case insensitive). "
|
||||
"It is also valid to not have the environment variable defined.");
|
||||
+ " (case insensitive)."
|
||||
+ (requireCredentialSpecifierEnvVarValue
|
||||
? ""
|
||||
: " It is also valid to not have the environment variable defined."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,3 +522,9 @@ TEST_P(LogMessagesForSpecificCredential, )
|
||||
|
||||
Logger::SetListener(nullptr);
|
||||
}
|
||||
|
||||
TEST(DefaultAzureCredential, RequireCredentialSpecifierEnvVarValue)
|
||||
{
|
||||
EXPECT_THROW(
|
||||
static_cast<void>(std::make_unique<DefaultAzureCredential>(true)), AuthenticationException);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user