From 31dc284164611a2f81feda3abaa7275a17e64fa1 Mon Sep 17 00:00:00 2001 From: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com> Date: Tue, 3 Aug 2021 12:11:24 -0700 Subject: [PATCH] Add samples for Azure Identity (#2692) Co-authored-by: Anton Kolesnyk --- sdk/identity/azure-identity/CMakeLists.txt | 4 ++ .../azure-identity/samples/CMakeLists.txt | 20 +++++++ .../samples/azure/service/client.hpp | 57 +++++++++++++++++++ .../samples/client_secret_credential.cpp | 39 +++++++++++++ .../samples/environment_credential.cpp | 33 +++++++++++ .../samples/managed_identity_credential.cpp | 33 +++++++++++ 6 files changed, 186 insertions(+) create mode 100644 sdk/identity/azure-identity/samples/CMakeLists.txt create mode 100644 sdk/identity/azure-identity/samples/azure/service/client.hpp create mode 100644 sdk/identity/azure-identity/samples/client_secret_credential.cpp create mode 100644 sdk/identity/azure-identity/samples/environment_credential.cpp create mode 100644 sdk/identity/azure-identity/samples/managed_identity_credential.cpp diff --git a/sdk/identity/azure-identity/CMakeLists.txt b/sdk/identity/azure-identity/CMakeLists.txt index 949a70085..5a099b0eb 100644 --- a/sdk/identity/azure-identity/CMakeLists.txt +++ b/sdk/identity/azure-identity/CMakeLists.txt @@ -91,3 +91,7 @@ endif() if (BUILD_PERFORMANCE_TESTS) add_subdirectory(test/perf) endif() + +if (AZ_ALL_LIBRARIES) + add_subdirectory(samples) +endif() diff --git a/sdk/identity/azure-identity/samples/CMakeLists.txt b/sdk/identity/azure-identity/samples/CMakeLists.txt new file mode 100644 index 000000000..e53bd35da --- /dev/null +++ b/sdk/identity/azure-identity/samples/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# SPDX-License-Identifier: MIT + +cmake_minimum_required (VERSION 3.13) + +project (azure-identity-samples LANGUAGES CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +add_executable(client_secret_credential_sample client_secret_credential.cpp) +target_link_libraries(client_secret_credential_sample PRIVATE azure-identity) +target_include_directories(client_secret_credential_sample PRIVATE .) + +add_executable(environment_credential_sample environment_credential.cpp) +target_link_libraries(environment_credential_sample PRIVATE azure-identity) +target_include_directories(environment_credential_sample PRIVATE .) + +add_executable(managed_identity_credential_sample managed_identity_credential.cpp) +target_link_libraries(managed_identity_credential_sample PRIVATE azure-identity) +target_include_directories(managed_identity_credential_sample PRIVATE .) diff --git a/sdk/identity/azure-identity/samples/azure/service/client.hpp b/sdk/identity/azure-identity/samples/azure/service/client.hpp new file mode 100644 index 000000000..c6af8fd31 --- /dev/null +++ b/sdk/identity/azure-identity/samples/azure/service/client.hpp @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include +#include + +namespace Azure { namespace Service { + + // This class is an oversimplified placeholder that is intended to represent an Azure SDK service + // client that uses Azure::Core::Credentials::TokenCredential to authenticate: Key Vault client, + // Storage Blobs client, etc. + class Client final { + private: + std::shared_ptr m_credential; + + public: + explicit Client( + const std::string& someParameter, + std::shared_ptr credential) + : m_credential(std::move(credential)) + { + static_cast(someParameter); // to suppress the "unused variable" warning. + } + + void DoSomething(const Core::Context& context) const + { + static_cast(context); // to suppress the "unused variable" warning. + + // This method does nothing, because the purpose of this class is to demonstrate + // how Azure::Identity classes can be used with a generic Azure SDK service client. + // If we have code here that gets the token, it would be up to the user to set it up to be + // valid enough to get a token, which is not critical for the intended demonstration purposes. + // And if user runs this, and authentication is unsuccessful, it may draw an unneccessary + // attention to an irrelevant (to the demo) point. + + // But an oversimplified logic of what a typical Azure SDK client does is below: +#if (0) + // Every client has its own scope. We use management.azure.com here as an example. + Core::Credentials::TokenRequestContext azureServiceClientContext; + azureServiceClientContext.Scopes = {"https://management.azure.com/"}; + + auto authenticationToken = m_credential->GetToken(azureServiceClientContext, context); + + // Now that it has a token, Client can authorize and DoSomething(). + // ... + // ... + + static_cast(authenticationToken); // to suppress the "unused variable" warning. +#endif + }; + }; + +}} // namespace Azure::Service diff --git a/sdk/identity/azure-identity/samples/client_secret_credential.cpp b/sdk/identity/azure-identity/samples/client_secret_credential.cpp new file mode 100644 index 000000000..249dfd01c --- /dev/null +++ b/sdk/identity/azure-identity/samples/client_secret_credential.cpp @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#include + +// These functions should be getting the real Tenant ID, Client ID, and the Client Secret to +// authenticate. It is recommended to NOT hardcode the secret in the code, but to get it from the +// envoronment or read it from a secure location. +std::string GetTenantId() { return std::string(); } +std::string GetClientId() { return std::string(); } +std::string GetClientSecret() { return std::string(); } + +int main() +{ + try + { + // Step 1: Initialize Cient Secret Credential. + auto clientSecretCredential = std::make_shared( + GetTenantId(), GetClientId(), GetClientSecret()); + + // Step 2: Pass the credential to an Azure Service Client. + Azure::Service::Client azureServiceClient("some parameter", clientSecretCredential); + + // Step 3: Start using the Azure Service Client. + azureServiceClient.DoSomething(Azure::Core::Context::ApplicationContext); + + std::cout << "Success!" << std::endl; + } + catch (const Azure::Core::Credentials::AuthenticationException& exception) + { + // Step 4 (optional/oversimplified): Handle authentication errors + // (invalid credential parameters, insufficient permissions). + std::cout << "Authentication error: " << exception.what() << std::endl; + } +} diff --git a/sdk/identity/azure-identity/samples/environment_credential.cpp b/sdk/identity/azure-identity/samples/environment_credential.cpp new file mode 100644 index 000000000..4f5f9f124 --- /dev/null +++ b/sdk/identity/azure-identity/samples/environment_credential.cpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#include + +int main() +{ + try + { + // Step 1: Create an EnvironmentCredential instance. + // Environment Credential would read its parameters from the environment variables, such as + // AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET. See documentation for details. + auto environmentCredential = std::make_shared(); + + // Step 2: Pass the credential to an Azure Service Client. + Azure::Service::Client azureServiceClient("some parameter", environmentCredential); + + // Step 3: Start using the Azure Service Client. + azureServiceClient.DoSomething(Azure::Core::Context::ApplicationContext); + + std::cout << "Success!" << std::endl; + } + catch (const Azure::Core::Credentials::AuthenticationException& exception) + { + // Step 4 (optional/oversimplified): Handle authentication errors + // (invalid credential parameters, insufficient permissions). + std::cout << "Authentication error: " << exception.what() << std::endl; + } +} diff --git a/sdk/identity/azure-identity/samples/managed_identity_credential.cpp b/sdk/identity/azure-identity/samples/managed_identity_credential.cpp new file mode 100644 index 000000000..a75e0e139 --- /dev/null +++ b/sdk/identity/azure-identity/samples/managed_identity_credential.cpp @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// SPDX-License-Identifier: MIT + +#include + +#include + +#include + +int main() +{ + try + { + // Step 1: Create a ManagedIdentityCredential instance. + // Managed Identity Credential would be available in some environments such as on Azure VMs. + // See documentation for details. + auto managedIdentityCredential = std::make_shared(); + + // Step 2: Pass the credential to an Azure Service Client. + Azure::Service::Client azureServiceClient("some parameter", managedIdentityCredential); + + // Step 3: Start using the Azure Service Client. + azureServiceClient.DoSomething(Azure::Core::Context::ApplicationContext); + + std::cout << "Success!" << std::endl; + } + catch (const Azure::Core::Credentials::AuthenticationException& exception) + { + // Step 4 (optional/oversimplified): Handle authentication errors + // (invalid credential parameters, insufficient permissions). + std::cout << "Authentication error: " << exception.what() << std::endl; + } +}