예제 #1
0
        public async Task TokenCacheRefresh()
        {
            // ensure expired tokens are refreshed
            var expired = new ManagedIdentityCredential()
            {
                Client = MockIdentityClient.ExpiredTokenClient
            };

            HashSet <string> tokens = new HashSet <string>();

            for (int i = 0; i < 100; i++)
            {
                Assert.IsTrue(tokens.Add(await expired.GetTokenAsync(MockScopes.Default)), "token failed to refresh");
            }

            // ensure non expired tokens are not refeshed
            var live = new ManagedIdentityCredential()
            {
                Client = MockIdentityClient.LiveTokenClient
            };

            tokens.Clear();

            tokens.Add(await live.GetTokenAsync(MockScopes.Default));

            for (int i = 0; i < 100; i++)
            {
                Assert.IsFalse(tokens.Add(await live.GetTokenAsync(MockScopes.Default)));
            }
        }
예제 #2
0
        public async Task VerifyAppService2019RequestWithClientIdMockAsync()
        {
            using (new TestEnvVar("IDENTITY_ENDPOINT", "https://identity.endpoint/"))
                using (new TestEnvVar("IDENTITY_HEADER", "mock-identity-header"))
                {
                    var expectedToken = "mock-access-token";
                    var response      = new MockResponse(200);
                    response.SetContent($"{{ \"access_token\": \"{expectedToken}\", \"expires_on\": \"3600\" }}");

                    var mockTransport = new MockTransport(response);
                    var options       = new TokenCredentialOptions {
                        Transport = mockTransport
                    };

                    ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential("mock-client-id", options));
                    AccessToken actualToken = await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default));

                    Assert.AreEqual(expectedToken, actualToken.Token);

                    MockRequest request = mockTransport.SingleRequest;
                    Assert.IsTrue(request.Uri.ToString().StartsWith(EnvironmentVariables.IdentityEndpoint));

                    string query = request.Uri.Query;
                    Assert.IsTrue(query.Contains("api-version=2019-08-01"));
                    Assert.IsTrue(query.Contains("client_id=mock-client-id"));
                    Assert.IsTrue(query.Contains($"resource={Uri.EscapeDataString(ScopeUtilities.ScopesToResource(MockScopes.Default))}"));
                    Assert.IsTrue(request.Headers.TryGetValue("X-IDENTITY-HEADER", out string identityHeader));

                    Assert.AreEqual(EnvironmentVariables.IdentityHeader, identityHeader);
                }
        }
예제 #3
0
        public async Task VerifyMSIRequest()
        {
            var pingResponse = new MockResponse(400);

            var response = new MockResponse(200);

            var expectedToken = "mock-msi-access-token";

            response.SetContent($"{{ \"access_token\": \"{expectedToken}\", \"expires_on\": 3600 }}");

            var mockTransport = new MockTransport(pingResponse, response);

            var options = new IdentityClientOptions()
            {
                Transport = mockTransport
            };

            var credential = new ManagedIdentityCredential(options: options);

            AccessToken actualToken = await credential.GetTokenAsync(MockScopes.Default);

            Assert.AreEqual(expectedToken, actualToken.Token);

            MockRequest request = mockTransport.Requests[1];

            string query = request.UriBuilder.Query;

            Assert.IsTrue(query.Contains("api-version=2018-02-01"));

            Assert.IsTrue(query.Contains($"resource={Uri.EscapeDataString(ScopeUtilities.ScopesToResource(MockScopes.Default))}"));

            Assert.IsTrue(request.Headers.TryGetValue("Metadata", out string metadataValue));

            Assert.AreEqual("true", metadataValue);
        }
        private async Task <string> GetAccessTokenAsync(CancellationToken cancellationToken)
        {
            if (!_cacheTokens)
            {
                return((await GetAccessTokenFromProviderAsync(cancellationToken)).Token);
            }
            await _semaphoreToken.WaitAsync(cancellationToken);

            try
            {
                //If the Token has more than 5 minutes Validity
                if (DateTime.UtcNow.AddMinutes(_cacheLifeTime) <= _token.ExpiresOn.UtcDateTime)
                {
                    return(_token.Token);
                }

                var credential = new ManagedIdentityCredential();
                var token      = await GetAccessTokenFromProviderAsync(cancellationToken);

                _token = token;

                return(token.Token);
            }
            finally
            {
                _semaphoreToken.Release();
            }
        }
        public void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            log.LogInformation(eventGridEvent.Data.ToString());
            if (adtInstanceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            }
            try
            {
                // Authenticate with Digital Twins
                // <ManagedIdentityCredential>
                var cred = new ManagedIdentityCredential("https://digitaltwins.azure.net");
                // </ManagedIdentityCredential>
                // <DigitalTwinsClient>
                var client = new DigitalTwinsClient(
                    new Uri(adtInstanceUrl),
                    cred,
                    new DigitalTwinsClientOptions
                {
                    Transport = new HttpClientTransport(singletonHttpClientInstance)
                });
                // </DigitalTwinsClient>
                log.LogInformation($"ADT service client connection created.");

                /*
                 * Add your business logic here.
                 */
            }
            catch (Exception e)
            {
                log.LogError(e.Message);
            }
        }
예제 #6
0
        /// <summary>
        /// Add Azure App Config
        ///
        /// You must have a secrets.json defined!
        ///
        /// Some Helpful Links:
        ///		Add a Key Vault Reference to App Configuration - https://docs.microsoft.com/en-us/azure/azure-app-configuration/use-key-vault-references-dotnet-core?tabs=cmd%2Ccore2x#add-a-key-vault-reference-to-app-configuration
        ///		App Config Best Practices - https://docs.microsoft.com/en-us/azure/azure-app-configuration/howto-best-practices
        ///		Feature Flags - https://docs.microsoft.com/en-us/azure/azure-app-configuration/concept-feature-management
        ///		Feature Flogs How To - https://docs.microsoft.com/en-us/azure/azure-app-configuration/howto-feature-filters-aspnet-core
        ///		Assign a Azure Config Access Policy - https://docs.microsoft.com/en-us/azure/azure-app-configuration/howto-integrate-azure-managed-service-identity?tabs=core2x
        ///		Using DefaultAzureCredentialOptions - https://www.rahulpnath.com/blog/defaultazurecredential_from_azure_sdk/?utm_source=site-bookmark
        /// </summary>
        /// <param name="debug">Check if debug for local settings vs. production</param>
        /// <param name="builder">The configuration builder object</param>
        /// <param name="initialConfig">The initial config that holds the app config objects</param>
        private static void AddAzureAppConfig(bool debug, ConfigurationBuilder builder, IConfigurationRoot initialConfig)
        {
            // You can call these variables anything you like, this is just what I defaulted them to
            // Please note that when you define a key in Azure App config it should be done with the following structure
            // Example: AppConfig:Database:ConnectionString
            // If you structure it like so it will automatically map to the AppConfig.cs object.  For this example it would map to AppConfig.Database.ConnectionString.
            try
            {
                Action <AzureAppConfigurationOptions> azureAppConfigOptions;
                if (debug)
                {
                    // There are two different ways to connect into this in development mode.
                    // The first is through the TenantID, AppId and AppSecret as shown below
                    azureAppConfigOptions = (options =>
                    {
                        // If you are using Azure Key Vault, you can connect it into App Config, see **Add a Key Vault Reference to App Configuration**
                        if (!string.IsNullOrEmpty(initialConfig["TenantId"]) && !string.IsNullOrEmpty(initialConfig["AppId"]) && !string.IsNullOrEmpty(initialConfig["AppSecret"]))
                        {
                            options.ConfigureKeyVault(kv => { kv.SetCredential(new ClientSecretCredential(initialConfig["TenantId"], initialConfig["AppId"], initialConfig["AppSecret"])); });
                        }

                        options.Connect(initialConfig["AzureAppConfigConnectionString"]);
                    });

                    // The other way to do it is through the DefaultAzureCredentials, see **Using DefaultAzureCredentialOptions**
                    // These default credentials SHOULD default to what you have setup in visual studio, but if they do not you can use the SharedTokenCacheUsername option
                    // This also assumes the developer has access to both the key vault and app config.
                    //azureAppConfigOptions = (options =>
                    //{
                    //	var azureCredentialOptions = new DefaultAzureCredentialOptions
                    //	{
                    //		SharedTokenCacheUsername = "******"
                    //	};
                    //	var credentials = new DefaultAzureCredential(azureCredentialOptions);

                    //	// If you are using Azure Key Vault, you can connect it into App Config, see **Assign a Azure Config Access Policy**
                    //	options.ConfigureKeyVault(kv => { kv.SetCredential(credentials); });
                    //	options.Connect(new Uri(initialConfig["AzureConfigUri"]), credentials);
                    //});
                }
                else
                {
                    // This assumes you have setup a service principle to access the App Config on behalf of this app, see **Assign a Key Vault Access Policy** above
                    azureAppConfigOptions = (options =>
                    {
                        var credentials = new ManagedIdentityCredential(initialConfig["AppId"]);

                        // If you are using Azure Key Vault, you can connect it into App Config, see **Assign a Azure Config Access Policy**
                        options.ConfigureKeyVault(kv => { kv.SetCredential(credentials); });
                        options.Connect(new Uri(initialConfig["AzureConfigUri"]), credentials);
                    });
                }

                builder.AddAzureAppConfiguration(azureAppConfigOptions);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
        private string GetAccessToken()
        {
            if (!_cacheTokens)
            {
                return(GetAccessTokenFromProvider().Token);
            }
            _semaphoreToken.Wait();
            try
            {
                //If the Token has more than 5 minutes Validity
                if (DateTime.UtcNow.AddMinutes(_cacheLifeTime) <= _token.ExpiresOn.UtcDateTime)
                {
                    return(_token.Token);
                }

                var credential = new ManagedIdentityCredential();
                var token      = GetAccessTokenFromProvider();

                _token = token;

                return(token.Token);
            }
            finally
            {
                _semaphoreToken.Release();
            }
        }
예제 #8
0
        // List blobs in a container
        public List <string> listBlobs(string containerUri, string identity = null, string prefix = null, string exclude = null)
        {
            var Cred            = new ManagedIdentityCredential(identity);
            var containerClient = new BlobContainerClient(new Uri(containerUri), Cred);

            containerClient.CreateIfNotExists();

            try
            {
                List <string> blobListing = new List <string>();
                if (exclude != null)
                { // apply --exclude regular expression
                    var rx = new Regex(exclude);
                    blobListing = containerClient.GetBlobs(prefix: prefix).Select(i => rx.IsMatch(i.Name) ? null : i.Name).ToList();
                    while (blobListing.Remove(null))
                    {
                    }
                    ;
                }
                else
                { // return full list
                    blobListing = containerClient.GetBlobs(prefix: prefix).Select(i => i.Name).ToList();
                }

                return(blobListing.Count == 0 ? null : blobListing);
            }
            catch (Exception ex)
            {
                throw IdentityError(identity, ex);
            }
        }
예제 #9
0
        // Get MSI access token
        public string getToken(string endpoint = "management", string identity = null, bool JWTformat = false)
        {
            var Cred = new ManagedIdentityCredential(identity);

            if (string.IsNullOrEmpty(endpoint))
            {
                endpoint = "management";
            }
            ;
            var Scope   = new String[] { $"https://{endpoint}.azure.com" };
            var Request = new TokenRequestContext(Scope);

            try
            {
                var Token = Cred.GetToken(Request);

                if (JWTformat)
                {
                    var stream    = Token.Token;
                    var handler   = new JwtSecurityTokenHandler();
                    var jsonToken = handler.ReadToken(stream);
                    var tokenS    = handler.ReadToken(stream) as JwtSecurityToken;
                    return(tokenS.ToString()); // decoded JSON Web Token
                }
                else
                {
                    return(Token.Token); // encoded JWT token
                }
            } catch (Exception ex)
            {
                throw IdentityError(identity, ex);
            }
        }
예제 #10
0
        //
        // execute GetSecret
        //

        public string Execute(string secretIdentifierUrl, string filePath = null, string identity = null)
        {
            (Uri keyVaultUri, string secretName, string secretVersion) = ValidateAndParseSecretURL(secretIdentifierUrl);

            var MIcredential = new ManagedIdentityCredential(identity);
            var secretClient = new SecretClient(keyVaultUri, MIcredential);

            // Retrieve a secret
            try
            {
                KeyVaultSecret secret      = secretClient.GetSecret(secretName, secretVersion);
                string         secretValue = secret.Value;

                if (String.IsNullOrEmpty(filePath))
                {   // print to stdout
                    return(secretValue);
                }
                else
                {   // creates or overwrites file and saves secret into it
                    File.WriteAllText(filePath, secretValue);
                    return("Saved");
                }
            } catch (Exception ex)
            {
                throw AzmiException.IDCheck(identity, ex);
            }
        }
예제 #11
0
        public async Task <string> GetAsync(string key)
        {
            TokenCredential tokenCredential;

            if (_azureKeyVaultConfigurationSettings.UseManagedIdentity)
            {
                tokenCredential = new ManagedIdentityCredential();
            }
            else
            {
                tokenCredential = new ClientSecretCredential(
                    _azureKeyVaultConfigurationSettings.TenantId,
                    _azureKeyVaultConfigurationSettings.ClientId,
                    _azureKeyVaultConfigurationSettings.ClientSecret);
            }
            var client = new SecretClient(new Uri(_azureKeyVaultConfigurationSettings.VaultUri), tokenCredential);

            //Key not found in local dictionary. Get it from Azure Key Vault and put it in local secrets store for later use
            var secret = await client.GetSecretAsync(key);

            if (secret == null || secret.Value == null || secret.Value.Value == null)
            {
                throw new ArgumentException($"The key {key} was not found in Azure Key Vault.");
            }

            return(secret.Value.Value);
        }
예제 #12
0
        public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
                                  webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
        {
            var settings = config.Build();
#if DEBUG
            config.AddAzureAppConfiguration(options =>
            {
                options.Connect(settings["ConnectionStrings:AppConfig"])
                .ConfigureKeyVault(kv =>
                {
                    kv.SetCredential(new DefaultAzureCredential());
                });
            });
#else
            var credentials = new ManagedIdentityCredential();
            config.AddAzureAppConfiguration(options =>
            {
                options.Connect(new Uri(settings["AppConfig:Endpoint"]), credentials)
                .ConfigureKeyVault(kv =>
                {
                    kv.SetCredential(credentials);
                });
            });
#endif
        })
                                  .UseStartup <Startup>());
예제 #13
0
        public void VerifyImdsUnavailableImmediateFailureMockAsync()
        {
            using (new TestEnvVar("MSI_ENDPOINT", null))
                using (new TestEnvVar("MSI_SECRET", null))
                {
                    var mockTransport = new MockTransport(request => throw new Exception("mock imds probe exception"));

                    var options = new TokenCredentialOptions()
                    {
                        Transport = mockTransport
                    };

                    ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential("mock-client-id", options));

                    Assert.ThrowsAsync <CredentialUnavailableException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));

                    MockRequest request = mockTransport.Requests[0];

                    string query = request.Uri.Query;

                    Assert.IsTrue(query.Contains("api-version=2018-02-01"));

                    Assert.False(request.Headers.TryGetValue("Metadata", out string _));
                }
        }
예제 #14
0
        /// <summary>
        /// Create the ServiceClientCredentials object based on the credentials
        /// supplied in local configuration file, or with a system managed identity.
        /// </summary>
        /// <param name="config">The param is of type ConfigWrapper. This class reads values from local configuration file.</param>
        /// <returns></returns>
        private static async Task <ServiceClientCredentials> GetCredentialsAsync(ConfigWrapper config)
        {
            var scopes = new[] { config.ArmAadAudience + "/.default" };

            string token;

            if (config.AadClientId != null) // Service Principal
            {
                var app = ConfidentialClientApplicationBuilder.Create(config.AadClientId)
                          .WithClientSecret(config.AadSecret)
                          .WithAuthority(AzureCloudInstance.AzurePublic, config.AadTenantId)
                          .Build();

                var authResult = await app.AcquireTokenForClient(scopes)
                                 .ExecuteAsync()
                                 .ConfigureAwait(false);

                token = authResult.AccessToken;
            }
            else // managed identity
            {
                var credential         = new ManagedIdentityCredential();
                var accessTokenRequest = await credential.GetTokenAsync(
                    new TokenRequestContext(
                        scopes : scopes
                        )
                    );

                token = accessTokenRequest.Token;
            }
            return(new TokenCredentials(token, TokenType));
        }
예제 #15
0
        //
        //
        //  **** Cmdlet start ****
        //
        //


        protected override void ProcessRecord()
        {
            var cred = new ManagedIdentityCredential(Identity);

            WriteVerbose($"Parsing secret... '{Secret}'");
            //(Uri keyVault, string secretName, string secretVersion) = ParseSecret(secrets);
            (Uri keyVault, string secretName, string secretVersion) = Shared.ParseUrl(Secret, "secrets");

            WriteVerbose($"Obtaining KV client for '{keyVault}' using '{Identity}'...");
            var secretClient = new SecretClient(keyVault, cred);

            WriteVerbose($"Obtaining secret {secretName}...");
            var secretValue = secretClient.GetSecret(secretName, secretVersion).Value.Value;

            // return value
            if (String.IsNullOrEmpty(File))
            {
                WriteObject(secretValue);
            }
            else
            {
                WriteVerbose($"Saving secret to file {File}...");
                System.IO.File.WriteAllText(File, secretValue);
                // TODO: Add test for file in current dir
                // TODO: Candidate for async
            }
        }
예제 #16
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            //var credential = new ClientSecretCredential("231dd9cd-ddc7-4fba-ae78-9f4ac3c912e7", "5f43fe5c-1c2b-4afa-97e6-fda41302e28b", "5ZlLakKHA:DE.6Jq-GbJWF=icJaCwW32");
            var credential = new ManagedIdentityCredential();
            var kvUri      = "https://kvswapana.vault.azure.net/";

            var           secretClient = new SecretClient(new Uri(kvUri), credential);
            var           encryptedDEK = secretClient.GetSecret("DEK");
            var           keyClient    = new KeyClient(new Uri(kvUri), credential);
            var           encryptedKEY = keyClient.GetKey("KEK");
            var           cryptoClient = new CryptographyClient(encryptedKEY.Value.Id, credential);
            DecryptResult decryptDek   = cryptoClient.Decrypt(EncryptionAlgorithm.RsaOaep256, Convert.FromBase64String(encryptedDEK.Value.Value));

            string  requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            name = name ?? data?.name;

            return(name != null
                   // Create MemoryStream
                ? (ActionResult) new OkObjectResult($"Hello, {name}, {encryptedKEY.Value.Id}, {Encoding.UTF8.GetString(decryptDek.Plaintext)}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body"));
        }
예제 #17
0
        //
        // Execute GetBlob
        //

        public string Execute(string blobURL, string filePath, string identity = null, bool ifNewer = false, bool deleteAfterCopy = false)
        {
            // method start

            // Connection
            var Cred       = new ManagedIdentityCredential(identity);
            var blobClient = new BlobClient(new Uri(blobURL), Cred);

            if (ifNewer && File.Exists(filePath) && !IsNewer(blobClient, filePath))
            {
                return("Skipped. Blob is not newer than file.");
            }

            try
            {
                string absolutePath = Path.GetFullPath(filePath);
                string dirName      = Path.GetDirectoryName(absolutePath);
                Directory.CreateDirectory(dirName);

                blobClient.DownloadTo(filePath);

                if (deleteAfterCopy)
                {
                    blobClient.Delete();
                }
                return("Success");
            } catch (Azure.RequestFailedException)
            {
                throw;
            } catch (Exception ex)
            {
                throw AzmiException.IDCheck(identity, ex);
            }
        }
예제 #18
0
        public async Task ValidateUserAssignedIdentity()
        {
            if (string.IsNullOrEmpty(TestEnvironment.SFEnable) || string.IsNullOrEmpty(TestEnvironment.UserAssignedVault))
            {
                Assert.Ignore();
            }

            using (ReadOrRestoreManagedIdentityEnvironment())
            {
                var vaultUri = new Uri(TestEnvironment.UserAssignedVault);

                var clientId = TestEnvironment.IMDSClientId;

                CredentialPipeline pipeline = CredentialPipeline.GetInstance(InstrumentClientOptions(new TokenCredentialOptions {
                    Transport = ServiceFabricManagedIdentitySource.GetServiceFabricMITransport()
                }));

                var cred = new ManagedIdentityCredential(new ManagedIdentityClient(new ManagedIdentityClientOptions {
                    Pipeline = pipeline, ClientId = clientId, PreserveTransport = true
                }));

                // Hard code service version or recorded tests will fail: https://github.com/Azure/azure-sdk-for-net/issues/10432
                var kvoptions = InstrumentClientOptions(new SecretClientOptions(SecretClientOptions.ServiceVersion.V7_0));

                var kvclient = InstrumentClient(new SecretClient(vaultUri, cred, kvoptions));

                KeyVaultSecret secret = await kvclient.SetSecretAsync("identitytestsecret", "value");

                Assert.IsNotNull(secret);
            }
        }
예제 #19
0
        private void InitializeAzureKeyVaultProvider()
        {
            // Initialize the Azure Key Vault provider
            TokenCredential            tokenCredential = null;
            SqlConnectionStringBuilder builder         = new SqlConnectionStringBuilder(Configuration.GetConnectionString("ContosoHRDatabase"));

            if (builder.Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity)
            {
                tokenCredential = new ManagedIdentityCredential();
            }
            else
            {
                var clientId = "...";
                var secret   = "...";
                var tenantId = "...";
                tokenCredential = new ClientSecretCredential(tenantId, clientId, secret);
            }
            SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider =
                new SqlColumnEncryptionAzureKeyVaultProvider(tokenCredential);

            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(
                customProviders: new Dictionary <string, SqlColumnEncryptionKeyStoreProvider>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
            {
                { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, sqlColumnEncryptionAzureKeyVaultProvider }
            }
                );
        }
예제 #20
0
        public void VerifyImdsAvailableUserCanceledMockAsync()
        {
            using (new TestEnvVar("MSI_ENDPOINT", null))
                using (new TestEnvVar("MSI_SECRET", null))
                {
                    var mockTransport = new MockTransport();

                    var options = new TokenCredentialOptions()
                    {
                        Transport = mockTransport
                    };

                    CancellationTokenSource cancellationSource = new CancellationTokenSource();

                    cancellationSource.Cancel();

                    var pipeline = CredentialPipeline.GetInstance(options);

                    ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(pipeline, new MockManagedIdentityClient(pipeline, "mock-client-id")
                    {
                        ImdsAvailableFunc = ct => { ct.ThrowIfCancellationRequested(); return(true); }
                    }));

                    Assert.CatchAsync <OperationCanceledException>(async() => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default), cancellationSource.Token));
                }
        }
예제 #21
0
        private async Task CreateDatalakeStorageAsync(IStorageAccount accountCreated, string fileSystemName, string defaultFolderName, string identityToGiveAccess)
        {
            this.logger.LogTrace($"Creating ADLS Gen2 File System {fileSystemName} in account {accountCreated.Name}...");

            // Create the basic parameters and the ADLS client proxy
            var creds   = default(Azure.Core.TokenCredential);
            var adlsUri = $"https://{accountCreated.Name}.dfs.core.windows.net";

            if (base.CredentialsUseSp)
            {
                creds = new ClientSecretCredential(base.TenantId, base.ClientId, base.ClientSecret);
            }
            else
            {
                creds = new ManagedIdentityCredential();
            }
            var adlsClient = new DataLakeServiceClient(new Uri(adlsUri), creds);

            // Create the file system with retry logic, should work on first attempt.
            await RetryActionAsync(async() => {
                this.logger.LogTrace("- Attempt to create file system...");
                var adlsFsClient = await adlsClient.CreateFileSystemAsync(fileSystemName);
                this.logger.LogTrace("- Attempt succeeded!");
            });

            // Creating the folder did require serveral retries until permissions propagated, correctly.
            await RetryActionAsync(async() => {
                this.logger.LogTrace("- Attempt to create folder.");
                var adlsFsClient = adlsClient.GetFileSystemClient(fileSystemName);
                await adlsFsClient.CreateDirectoryAsync(defaultFolderName);
                this.logger.LogTrace("- Attempt succeeded!");
            });

            this.logger.LogTrace($"ADLS File System {fileSystemName} created!");
        }
예제 #22
0
        private static BlobClient GetBlobClient(ILogger log,
                                                string mode,
                                                string miClientID,
                                                string storageEndPoint,
                                                string clientId,
                                                string clientSecret,
                                                string tennat,
                                                string blobContainerName,
                                                string blobName)
        {
            log.LogInformation($"will access using {mode}");
            Azure.Identity.TokenCredentialOptions options = default;
            ClientSecretCredential    spnToken            = new ClientSecretCredential(tennat, clientId, clientSecret);
            ManagedIdentityCredential token = new ManagedIdentityCredential(miClientID, options);
            string saConnectionString       = "";

            // note, that in a real impl, only one type should be used
            if (mode.Equals("spn"))
            {
                var client = new SecretClient(new Uri("https://gensaskv.vault.azure.net/"), spnToken);
                saConnectionString = client.GetSecret("sa-cs").Value.Value;
            }
            else
            {
                var client = new SecretClient(new Uri("https://gensaskv.vault.azure.net/"), token);
                saConnectionString = client.GetSecret("sa-cs").Value.Value;
            }

            BlobClient blobClient = new BlobClient(saConnectionString, blobContainerName, blobName);

            log.LogInformation($"got blob client via token, blobClient.CanGenerateSasUri ? {blobClient.CanGenerateSasUri}");
            return(blobClient);
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var managedIdentityClientId = Environment.GetEnvironmentVariable("MANAGED_IDENTITY_CLIENT_ID");
            var configurationEndpoint   = Environment.GetEnvironmentVariable("CONFIGURATION_ENDPOINT");

            var managedIdentityCredential = new ManagedIdentityCredential(managedIdentityClientId);
            var configurationEndpointUri  = new Uri(configurationEndpoint);

            IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

            configurationBuilder.AddAzureAppConfiguration(options => {
                options.Connect(configurationEndpointUri, managedIdentityCredential);
                options.ConfigureKeyVault(opt => {
                    opt.SetCredential(managedIdentityCredential);
                });
            });
            var name = configurationBuilder.Build() ["tst"];

            log.LogInformation("C# HTTP trigger function processed a request.");

            return(name != null ?
                   (ActionResult) new OkObjectResult($"Hello, {name}") :
                   new BadRequestObjectResult("Please pass a name on the query string or in the request body"));
        }
        public async Task <string> GetSecretAsApplicationUsingUserManagedIdentityAsync()
        {
            logger.LogInformation("----- User Assigned Managed Identity");

            SecretClientOptions options = KeyVaultUtility.CreateSecretClientOptions();

            var credentials = new ManagedIdentityCredential(keyVaultConfiguration.UserAssignedManagedIdentityClientId);

            var keyVault = keyVaultConfiguration.Url;
            var client   = new SecretClient(new Uri(keyVault), credentials, options);

            KeyVaultSecret secret = null;

            try
            {
                secret = await client.GetSecretAsync(keyVaultConfiguration.SecretName);

                return(secret.Value);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Failed to get secret as managed identity");
                throw;
            }
        }
예제 #25
0
        // Initialize the Azure Key Vault provider for Always Encrypted. Required if column master keys are stored in Azure Key Vault.
        private void InitializeAzureKeyVaultProvider()
        {
            TokenCredential            tokenCredential = null;
            SqlConnectionStringBuilder builder         = new SqlConnectionStringBuilder(Configuration.GetConnectionString("ContosoHRDatabase"));

            if (builder.Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity)
            {
                // If the application uses a managed identity to talk to Azure SQL Database, use the managed identity for Azure Key Vault too.
                tokenCredential = new ManagedIdentityCredential();
            }
            else
            {
                // Assume a managed identity is not available to the app. Instead, use a client id/secret to authenticate to Azure Key Vault.
                // Fetch client id, secret, tenant id from the configuration.
                // It is recommended you specify these parameters in secrets.json.
                // See https://docs.microsoft.com/aspnet/core/security/app-secrets?view=aspnetcore-5.0&tabs=windows on how store secrets in secrets.json.
                var clientId = Configuration["ClientId"];
                var secret   = Configuration["Secret"];
                var tenantId = Configuration["TenantId"];
                tokenCredential = new ClientSecretCredential(tenantId, clientId, secret);
            }
            SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider =
                new SqlColumnEncryptionAzureKeyVaultProvider(tokenCredential);

            SqlConnection.RegisterColumnEncryptionKeyStoreProviders(
                customProviders: new Dictionary <string, SqlColumnEncryptionKeyStoreProvider>(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
            {
                { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, sqlColumnEncryptionAzureKeyVaultProvider }
            }
                );
        }
예제 #26
0
        private void ProcessMulti()
        {
            WriteVerbose("Starting to process a container");
            // Connection
            var cred            = new ManagedIdentityCredential(Identity);
            var containerClient = new BlobContainerClient(new Uri(Container), cred);

            // fix path
            Directory ??= Container.Split('/').Last();
            Directory = Path.GetFullPath(Directory, SessionState.Path.CurrentLocation.Path);
            WriteVerbose($"Using source: '{Directory}'");

            // get list of files
            WriteVerbose("Obtaining list of files...");
            var fileList = System.IO.Directory.EnumerateFiles(Directory, "*", SearchOption.AllDirectories);

            WriteVerbose($"Obtained {fileList.Count()} files");

            // apply -Exclude regular expression
            if (!String.IsNullOrEmpty(Exclude))
            {
                WriteVerbose("Filtering list of files...");
                Regex excludeRegEx = new Regex(Exclude);
                fileList = fileList.Where(file => !excludeRegEx.IsMatch(file));
                WriteVerbose($"Filtered to {fileList.Count()} files");
            }

            Parallel.ForEach(fileList, file =>
            {
                var blobPath          = file.Substring(Directory.Length).TrimStart(Path.DirectorySeparatorChar);
                BlobClient blobClient = containerClient.GetBlobClient(blobPath);
                blobClient.Upload(file, Force);
            });
            WriteVerbose("Upload completed");
        }
예제 #27
0
        private void ProcessSingle()
        {
            WriteVerbose("Starting to process a single blob");
            // Connection
            var cred       = new ManagedIdentityCredential(Identity);
            var blobClient = new BlobClient(new Uri(Blob), cred);

            if (String.IsNullOrEmpty(Content))
            {
                // Fix path
                File ??= Blob.Split('/').Last();
                File = Path.GetFullPath(File, SessionState.Path.CurrentLocation.Path);
                WriteVerbose($"Using source: '{File}'");
            }
            else
            {
                // create temporary file and fill content
                File = Path.GetTempFileName();
                System.IO.File.WriteAllText(File, Content);
                WriteVerbose($"Using temporary file: '{File}'");
            }
            // Download
            blobClient.Upload(File, Force);
            WriteVerbose("Upload completed");
            if (!String.IsNullOrEmpty(Content))
            {
                System.IO.File.Delete(File);
                WriteVerbose($"Deleted temporary file: '{File}'");
            }
        }
        public async void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            // After this is deployed, you need to turn the Managed Identity Status to "On",
            // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role to this function identity
            // in order for this function to be authorized on ADT APIs.

            log.LogInformation(eventGridEvent.Data.ToString());
            try
            {
                // Authenticate on ADT APIs
                var cred   = new ManagedIdentityCredential(adtAppId);
                var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                    Transport = new HttpClientTransport(httpClient)
                });
                log.LogInformation($"ADT service client connection created.");

                if (client != null)
                {
                    if (eventGridEvent != null && eventGridEvent.Data != null)
                    {
                        #region Open this region for message format information
                        // Telemetry message format
                        //{
                        //  "properties": { },
                        //  "systemProperties":
                        // {
                        //    "iothub-connection-device-id": "thermostat1",
                        //    "iothub-connection-auth-method": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}",
                        //    "iothub-connection-auth-generation-id": "637199981642612179",
                        //    "iothub-enqueuedtime": "2020-03-18T18:35:08.269Z",
                        //    "iothub-message-source": "Telemetry"
                        //  },
                        //  "body": "eyJUZW1wZXJhdHVyZSI6NzAuOTI3MjM0MDg3MTA1NDg5fQ=="
                        //}
                        #endregion

                        // Reading deviceId from message headers
                        log.LogInformation(eventGridEvent.Data.ToString());
                        JObject job      = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());
                        string  deviceId = (string)job["systemProperties"]["iothub-connection-device-id"];
                        log.LogInformation($"Found device: {deviceId}");

                        // Extracting temperature from device telemetry
                        byte[] body         = Convert.FromBase64String(job["body"].ToString());
                        var    value        = Encoding.ASCII.GetString(body);
                        var    bodyProperty = (JObject)JsonConvert.DeserializeObject(value);
                        JToken temperature  = bodyProperty["Temperature"];
                        log.LogInformation($"Device Temperature is ({temperature.Type}): {temperature}");

                        // Update device Temperature property
                        await AdtUtilities.UpdateTwinPropertyAsync(client, deviceId, "/Temperature", temperature.Value <float>(), log);
                    }
                }
            }
            catch (Exception e)
            {
                log.LogError($"Error: {e.Message}");
            }
        }
        public static async Task Run(
            [EventHubTrigger("deviceevents", Connection = "EVENTHUB_CONNECTIONSTRING")] EventData[] events, ILogger log)
        {
            // After this is deployed, you need to turn the Managed Identity Status to "On",
            // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role
            // to this function identity in order for this function to be authorized on ADT APIs.
            if (adtInstanceUrl == null)
            {
                log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            }

            var exceptions = new List <Exception>();

            foreach (EventData eventData in events)
            {
                try
                {
                    // Get message body
                    string messageBody = Encoding.UTF8.GetString(eventData.Body.Array, eventData.Body.Offset, eventData.Body.Count);

                    // Create Digital Twin client
                    var cred   = new ManagedIdentityCredential("https://digitaltwins.azure.net");
                    var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                        Transport = new HttpClientTransport(httpClient)
                    });

                    // Reading Device ID from message headers
                    JObject jbody    = (JObject)JsonConvert.DeserializeObject(messageBody);
                    string  deviceId = eventData.SystemProperties["iothub-connection-device-id"].ToString();

                    string dtId = deviceId; // simple mapping

                    // Extracting temperature from device telemetry
                    double temperature = Convert.ToDouble(jbody["Temperature"].ToString());

                    // Update device Temperature property
                    UpdateOperationsUtility uou = new UpdateOperationsUtility();
                    uou.AppendAddOp("/Temperature", temperature);
                    await client.UpdateDigitalTwinAsync(dtId, uou.Serialize());

                    log.LogInformation($"Updated Temperature of device Twin '{dtId}' to: {temperature}");
                }
                catch (Exception e)
                {
                    // We need to keep processing the rest of the batch - capture this exception and continue.
                    exceptions.Add(e);
                }
            }

            if (exceptions.Count > 1)
            {
                throw new AggregateException(exceptions);
            }

            if (exceptions.Count == 1)
            {
                throw exceptions.Single();
            }
        }
예제 #30
0
        public static async Task Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            // After this is deployed, you need to turn the Identity Status "On",
            // Grab Object Id of the function and assigned "Azure Digital Twins Owner (Preview)" role to this function identity
            // in order for this function to be authorize on ADT APIs.

            DigitalTwinsClient client;

            try
            {
                ManagedIdentityCredential cred = new ManagedIdentityCredential(adtAppId);
                client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred, new DigitalTwinsClientOptions {
                    Transport = new HttpClientTransport(httpClient)
                });
            }
            catch (Exception e)
            {
                log.LogError($"ADT service client connection failed. {e}");
                return;
            }

            if (client != null)
            {
                try
                {
                    if (eventGridEvent != null && eventGridEvent.Data != null)
                    {
                        string  twinId  = eventGridEvent.Subject.ToString();
                        JObject message = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());

                        //log.LogInformation($"Reading event from {twinId}: {eventGridEvent.EventType}: {message["data"]}");

                        //Find and update parent Twin
                        string parentId = await AdtUtilities.FindParentAsync(client, twinId, "contains", log);

                        if (parentId != null)
                        {
                            // Read properties which values have been changed in each operation
                            foreach (var operation in message["data"]["patch"])
                            {
                                string opValue = (string)operation["op"];
                                if (opValue.Equals("replace"))
                                {
                                    string propertyPath = ((string)operation["path"]);
                                    if (propertyPath.Equals("/Temperature") || (propertyPath.Equals("/HumidityLevel")))
                                    {
                                        await AdtUtilities.UpdateTwinPropertyAsync(client, parentId, propertyPath, operation["value"].Value <float>(), log);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    log.LogError(e.ToString());
                }
            }
        }