//GetSettingFromKeyVault public static string GetValueFomKeyVault(string Key) { var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); string keyVaultURL = GetValue(Key); var connStr = (kv.GetSecretAsync(keyVaultURL)).GetAwaiter().GetResult().Value; string s = connStr.ToString(); return s; }
static async Task MainAsync(string[] args) { var keyClient = new KeyVaultClient((authority, resource, scope) => { var adCredential = new ClientCredential(applicationId, applicationSecret); var authenticationContext = new AuthenticationContext(authority, null); return authenticationContext.AcquireToken(resource, adCredential).AccessToken; }); // Get the key details var keyIdentifier = "https://testvaultrahul.vault.azure.net/keys/rahulkey/0f653b06c1d94159bc7090596bbf7784"; var key = await keyClient.GetKeyAsync(keyIdentifier); var publicKey = Convert.ToBase64String(key.Key.N); using (var rsa = new RSACryptoServiceProvider()) { var p = new RSAParameters() { Modulus = key.Key.N, Exponent = key.Key.E }; rsa.ImportParameters(p); var byteData = Encoding.Unicode.GetBytes(textToEncrypt); // Encrypt and Decrypt var encryptedText = rsa.Encrypt(byteData, true); var decryptedData = await keyClient.DecryptDataAsync(keyIdentifier, "RSA_OAEP", encryptedText); var decryptedText = Encoding.Unicode.GetString(decryptedData.Result); // Sign and Verify var hasher = new SHA256CryptoServiceProvider(); var digest = hasher.ComputeHash(byteData); var signature = await keyClient.SignAsync(keyIdentifier, "RS256", digest); var isVerified = rsa.VerifyHash(digest, "Sha256", signature.Result); } }
/// <summary> /// Creates a new Key Vault KeyResolver that uses the specified KeyVaultClient /// and only resolves keys for the specified key vault /// </summary> /// <param name="vaultName">The URL for the Key Vault, e.g. https://myvault.vault.azure.net/ </param> /// <param name="client">Key Vault client</param> public KeyVaultKeyResolver( string vaultName, KeyVaultClient client ) { if ( string.IsNullOrWhiteSpace( vaultName ) ) throw new ArgumentNullException( "vaultName" ); if ( client == null ) throw new ArgumentNullException( "client" ); _name = NormalizeVaultName( vaultName ); _client = client; }
static void KeyVaultSecretsDemo() { // Use Key for authorization AccessToken var keyVaultClient = new KeyVaultClient(GetAccessToken, new HttpClient()); // Use Certificate for authorization AccessToken // var keyVaultClient = new KeyVaultClient(GetAccessCertificateToken, new HttpClient()); var keyVaultAddress = ConfigurationManager.AppSettings["VaultUrl"]; // Get connection string without password var connectionString = keyVaultClient.GetSecretAsync(keyVaultAddress, "ConnectionStringsWilco").GetAwaiter().GetResult(); var builder = new SqlConnectionStringBuilder(connectionString.Value); // Get password var password = keyVaultClient.GetSecretAsync(keyVaultAddress, "SqlPasswordWilco").GetAwaiter().GetResult(); // Convert password to SecureString. 'password.Value' object still keeps it in plain text. Hopefuly this is the only reference. // The reason to keep password out of connection string is to minimize number of it's instances in managed heap. var securePassword = new SecureString(); foreach (char c in password.Value) { securePassword.AppendChar(c); } securePassword.MakeReadOnly(); // Allow GC to collect it password = null; // Keep connection in SqlCredential. When connection goes to pool or paged to disk credentials are not exposed. var credentials = new SqlCredential(builder.UserID, securePassword); builder.UserID = string.Empty; // Need to clen up user id as SqlCredential won't attach to sql connection // Put connection string and credentials in cache. We don't want to fetch connection string each time from KV. // Remove callback policy is designed to dispose objects. In case of SecureString it should be packed with '0'oz. MemoryCache.Default.Add("ConnectionStringsWilco", builder.ConnectionString, new CacheItemPolicy { RemovedCallback = DisposePolicyRemovedCallback }); MemoryCache.Default.Add("SqlCredentialsWilco", credentials, new CacheItemPolicy { RemovedCallback = DisposePolicyRemovedCallback }); BusinessOperation(); Console.ReadLine(); }
public KeyVaultService(string vaultUrl, string appId, string appSecret) { _vaultUrl = vaultUrl; _appId = appId; _appSecret = appSecret; _keyVaultClient = new KeyVaultClient(GetAccessTokenAsync); }
static KeyVaultAccessor() { keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); var clientAssertionCertPfx = CertificateHelper.FindCertificateByThumbprint(CloudConfigurationManager.GetSetting(Constants.KeyVaultAuthCertThumbprintSetting)); var client_id = CloudConfigurationManager.GetSetting(Constants.KeyVaultAuthClientIdSetting); assertionCert = new ClientAssertionCertificate(client_id, clientAssertionCertPfx); }
static void Main(string[] args) { var client = new KeyVaultClient(Authenticate); GetKeys(client); Console.ReadKey(); }
public KeyVaultKeyRepository(KeyVaultConfiguration keyVaultConfiguration) { this.keyVaultConfiguration = keyVaultConfiguration; // TODO : Move this into a common provider as it is used in multiple places this.keyVaultClient = new KeyVaultClient(this.HandleKeyVaultAuthenticationCallback); }
/// <summary> /// Creates a secret in Azure Key Vault and returns its ID. /// </summary> /// <param name="secretName">The name of the secret to create.</param> /// <returns>The ID of the secret created.</returns> public static string SetUpKeyVaultSecret(string secretName) { KeyVaultClient cloudVault = new KeyVaultClient(GetAccessToken); string vaultUri = CloudConfigurationManager.GetSetting("VaultUri"); try { // Delete the secret if it exists. cloudVault.DeleteSecretAsync(vaultUri, secretName).GetAwaiter().GetResult(); } catch (KeyVaultClientException ex) { if (ex.Status != System.Net.HttpStatusCode.NotFound) { Console.WriteLine("Unable to access the specified vault. Please confirm the KVClientId, KVClientKey, and VaultUri are valid in the app.config file."); Console.WriteLine("Also ensure that the client ID has previously been granted full permissions for Key Vault secrets using the Set-AzureKeyVaultAccessPolicy command with the -PermissionsToSecrets parameter."); Console.WriteLine("Press any key to exit"); Console.ReadLine(); throw; } } // Create a 256bit symmetric key and convert it to Base64. SymmetricKey symmetricKey = new SymmetricKey(secretName, SymmetricKey.KeySize256); string symmetricBytes = Convert.ToBase64String(symmetricKey.Key); // Store the Base64 of the key in the key vault. Note that the content-type of the secret must // be application/octet-stream or the KeyVaultKeyResolver will not load it as a key. Secret cloudSecret = cloudVault.SetSecretAsync(vaultUri, secretName, symmetricBytes, null, "application/octet-stream").GetAwaiter().GetResult(); // Return the base identifier of the secret. This will be resolved to the current version of the secret. return cloudSecret.SecretIdentifier.BaseIdentifier; }
public KeyVault(string clientId, string clientSecret, string vaultUri, bool checkIfKeyExistsBeforeGet) { _clientId = clientId; _clientSecret = clientSecret; _vaultUri = vaultUri; _checkIfKeyExistsBeforeGet = checkIfKeyExistsBeforeGet; _keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); }
public KeyVaultSecretStore(string vaultName, string clientId, string clientKey) { _vaultName = vaultName; _clientId = clientId; _clientKey = clientKey; _keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); }
public KeyVaultService(string clientId, string clientSecret, string keyVaultUri) { this.clientId = clientId; this.clientSecret = clientSecret; this.keyVaultUri = keyVaultUri; clientCredential = new ClientCredential(clientId, clientSecret); keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken), GetHttpClient()); }
/// <summary> /// Create a new Key Vault KeyResolver that uses the specified KeyVaultClient /// </summary> /// <param name="client">Key Vault client</param> public KeyVaultKeyResolver( KeyVaultClient client ) { if ( client == null ) throw new ArgumentNullException( "client" ); _name = null; _client = client; }
public async Task<IEnumerable<JsonWebKey>> GetAsync() { if (_jwk == null) { var keyVaultClient = new KeyVaultClient(_authentication.KeyVaultClientAuthenticationCallback); var keyBundle = await keyVaultClient.GetKeyAsync(_options.KeyIdentifier).ConfigureAwait(false); _jwk = new JsonWebKey(keyBundle.Key.ToString()); } return new List<JsonWebKey> { _jwk }; }
public async Task<IEnumerable<string>> Get() { if (false) //DONT RUN { var keyvaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); var secrets = await keyvaultClient.GetSecretsAsync("https://ascend-xyz-testing-weu.vault.azure.net"); } //Using the abstraction we can do var storageKey = config.GetAzureKeyVaultSecret("storage"); return new string[] { "value1", "value2" }; }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // I put my GetToken method in a Utils class. Change for wherever you placed your method. var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(Utils.GetToken)); var sec = kv.GetSecretAsync(WebConfigurationManager.AppSettings["SecretUri"]).Result.Value; //I put a variable in a Utils class to hold the secret for general application use. Utils.EncryptSecret = sec; }
/// <summary> /// /// </summary> /// <returns></returns> private Dictionary<String, String> retrieveSecrets(bool cert) { Dictionary<string, string> keyValues = new Dictionary<string, string>(); KeyVaultClient kv; if (cert) { kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); } else { kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken)); } List<string> secrets = new List<string>(); var values = kv.GetSecretsAsync(this.Configuration.GetSection("General").GetSection("KeyVaultURI").Value.ToString()).GetAwaiter().GetResult(); if (values != null && values.Value != null) { foreach (var m in values.Value) secrets.Add(m.Identifier.Name); } while (values != null && !string.IsNullOrWhiteSpace(values.NextLink)) { values = kv.GetSecretsNextAsync(values.NextLink).GetAwaiter().GetResult(); if (values != null && values.Value != null) { foreach (var m in values.Value) secrets.Add(m.Identifier.Name); } } foreach (var value in secrets) { var secret = kv.GetSecretAsync(this.Configuration.GetSection("General").GetSection("KeyVaultURI").Value.ToString(), value).GetAwaiter().GetResult(); keyValues.Add(value.Replace("-",":"), secret.Value); } return keyValues; }
public async Task<byte[]> Sign(byte[] digest) { if (digest == null) throw new ArgumentNullException("digest"); if (digest.Length != 32) throw new ArgumentException("The value must have 32 bytes", "digest"); var client = new KeyVaultClient(GetAccessToken); var keyVaultSettings = Settings.Get<KeyVaultSettings>(); var signResult = await client.SignAsync( keyVaultSettings.KeyId, keyVaultSettings.Algorithm, digest); return signResult.Result; }
internal KeyVaultKey( KeyVaultClient client, KeyBundle keyBundle ) { switch ( keyBundle.Key.Kty ) { case JsonWebKeyType.Rsa: _implementation = new RsaKey( keyBundle.Key.Kid, keyBundle.Key.ToRSA() ); break; case JsonWebKeyType.RsaHsm: _implementation = new RsaKey( keyBundle.Key.Kid, keyBundle.Key.ToRSA() ); break; } if ( _implementation == null ) throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The key type \"{0}\" is not supported", keyBundle.Key.Kty ) ); _client = client; }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // I put my GetToken method in a Utils class. Change for wherever you placed your method. var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(Util.GetToken)); var sec = kv.GetSecretsAsync(WebConfigurationManager.AppSettings["VaultUri"]).GetAwaiter().GetResult(); //I put a variable in a Utils class to hold the secret for general application use. Util.EncryptSecret = new List<KeyValuePair<string, string>>(); foreach (var item in sec.Value) { var value = kv.GetSecretAsync(item.Id).GetAwaiter().GetResult().Value; Util.EncryptSecret.Add(new KeyValuePair<string, string>(item.Identifier.Name, value)); } }
private static void KeyVaultEncryptionDemo() { // Use Certificate for authorization AccessToken var keyVaultClient = new KeyVaultClient(GetAccessCertificateToken, new HttpClient()); Console.Write("Password:"******"KeyId"]; var encryptedPasswordBytes = keyVaultClient.EncryptAsync(keyId, JsonWebKeyEncryptionAlgorithm.RSAOAEP, System.Text.Encoding.UTF8.GetBytes(password)) .GetAwaiter() .GetResult() .Result; Console.WriteLine("Encrypted password:{0}", System.Text.Encoding.UTF8.GetString(encryptedPasswordBytes)); Console.WriteLine("decrypting..."); var decryptedPasswordBytes = keyVaultClient.DecryptAsync(keyId, JsonWebKeyEncryptionAlgorithm.RSAOAEP, encryptedPasswordBytes) .GetAwaiter() .GetResult() .Result; Console.WriteLine("Decrypted password:{0}", System.Text.Encoding.UTF8.GetString(decryptedPasswordBytes)); }
/// <summary> /// /// </summary> /// <param name="keyIdentifier"></param> /// <param name="algorithm">A valid and supported <see cref="JsonWebKeySignatureAlgorithm"/> value. Note: <see cref="JsonWebKeySignatureAlgorithm.RSNULL"/> is not supported.</param> /// <param name="keyVaultClient"></param> /// <exception cref="ArgumentException">RSNULL is not allowed in this scenario.</exception> /// <exception cref="ArgumentException">Supplied value is not a currently supported JsonWebKeySignatureAlgorithm value.</exception> public AzureKeyVaultSignatureProvider(string keyIdentifier, string algorithm, KeyVaultClient keyVaultClient) { _keyIdentifier = keyIdentifier; _algorithm = algorithm; switch (algorithm) { case JsonWebKeySignatureAlgorithm.RS256: _hashAlgorithm = SHA256.Create(); break; case JsonWebKeySignatureAlgorithm.RS384: _hashAlgorithm = SHA384.Create(); break; case JsonWebKeySignatureAlgorithm.RS512: _hashAlgorithm = SHA512.Create(); break; case JsonWebKeySignatureAlgorithm.RSNULL: throw new ArgumentException("RSNULL is not allowed in this scenario.", algorithm); default: throw new ArgumentException(algorithm + " is not a currently supported JsonWebKeySignatureAlgorithm value.", algorithm); } _keyVaultClient = keyVaultClient; }
public KeyVaultScampClient(IConfiguration configuration) { _configuration = configuration; _keyVaultUrl = _configuration["KeyVault:Url"]; if (_keyVaultUrl == null) { _keyVaultClient = null; } else { #if DEBUG //This should be used only during development _keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); #else //This use certificate service in Azure platform and doesn't need shared keys _keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken)); clientAssertionCertPfx = FindCertificateByThumbprint(_configuration["KeyVault:AuthCertThumbprintSetting"]); #endif } }
public KeyVaultConfigurationProvider(string keyVaultUri, string clientId, string clientSecret) { if (string.IsNullOrEmpty(keyVaultUri)) { throw new ArgumentNullException(nameof(keyVaultUri)); } if (string.IsNullOrWhiteSpace(clientId)) { clientId = Environment.GetEnvironmentVariable("ClientId"); } if (string.IsNullOrWhiteSpace(clientSecret)) { clientSecret = Environment.GetEnvironmentVariable("ClientSecret"); } if (string.IsNullOrWhiteSpace("clientId")) { throw new InvalidOperationException("Did not find required env var ClientId"); } if (string.IsNullOrWhiteSpace(clientSecret)) { throw new InvalidOperationException("Did not find required env var ClientSecret"); } KeyVaultUri = keyVaultUri; ClientId = clientId; ClientSecret = clientSecret; VaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(KeyUtils.GetToken)); }
private static async Task<string> GetKeys(KeyVaultClient keyVaultClient) { var keyIdentifier = "keyIdentifier"; var textToEncrypt = "This is a test message"; var byteData = Encoding.Unicode.GetBytes(textToEncrypt); var hasher = new SHA256CryptoServiceProvider(); var digest = hasher.ComputeHash(byteData); var signedResult = await keyVaultClient.SignAsync( keyIdentifier, JsonWebKeySignatureAlgorithm.RS256, digest); var isVerified = await keyVaultClient.VerifyAsync(keyIdentifier, "RS256", digest, signedResult.Result); var keyResult = await keyVaultClient.GetKeyAsync(keyIdentifier); var jsonWebKey = keyResult.Key.ToString(); var key = JsonConvert.DeserializeObject<JsonWebKey>(jsonWebKey); var rsa = new RSACryptoServiceProvider(); var p = new RSAParameters() { Modulus = key.N, Exponent = key.E }; rsa.ImportParameters(p); isVerified = rsa.VerifyHash(digest, "Sha256", signedResult.Result); return null; }
public AzureKeyVaultExternalSigner(KeyVaultClient keyVaultClient, string vaultUrl) { KeyVaultClient = keyVaultClient; VaultUrl = vaultUrl; }
//Write a Secert to Key Vault public async void WriteSecret(string secretName, string secretValue) { AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); await keyVaultClient.SetSecretAsync("https://reubenkv.vault.azure.net/", secretName, secretValue, null, "text"); }
/// <summary> /// /// </summary> /// <param name="keyIdentifier"></param> /// <param name="algorithm">A valid and supported <see cref="JsonWebKeySignatureAlgorithm"/> value. Note: <see cref="JsonWebKeySignatureAlgorithm.RSNULL"/> is not supported.</param> /// <param name="keyVaultAuthenticationCallback"></param> /// <exception cref="ArgumentException">RSNULL is not allowed in this scenario.</exception> /// <exception cref="ArgumentException">Supplied value is not a currently supported JsonWebKeySignatureAlgorithm value.</exception> public AzureKeyVaultSignatureProvider(string keyIdentifier, string algorithm, KeyVaultClient.AuthenticationCallback keyVaultAuthenticationCallback) : this(keyIdentifier, algorithm, new KeyVaultClient(keyVaultAuthenticationCallback)) { }
static async Task Main() { // Change variables below to configure the application. // Name of the self signed certificate in keyvault. var selfSignedKeyVaultName = ""; // Name of the certificate signed by Let's Encrypt. var letsEncryptedKeyVaultName = ""; // The subject for the self signed certificate. // Most likely something like CN=contoso.com var subjectName = ""; // Subject alternative names // Most likely contoso.com var subjectAlternativeNames = new List <string>(); // Tags for the resources created in keyvault. var tags = new Dictionary <string, string> { { "cert-type", "Let's Encrypt" } }; // The type of certificate you'd like to request for. var keyProperties = new KeyProperties() { KeyType = JsonWebKeyType.EllipticCurve, Curve = JsonWebKeyCurveName.P256, }; // Don't change below unless you want to. var configuration = new ConfigurationBuilder() .SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)) .AddJsonFile("appsettings.json") .Build(); var serviceCollection = new ServiceCollection(); serviceCollection.AddOptions(); serviceCollection.Configure <Settings>(options => configuration.GetSection(nameof(Settings)).Bind(options)); serviceCollection.AddScoped <IKeyVaultClient, KeyVaultClient>((sp) => { var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(async(authority, resource, scope) => { var azureAuthenticationService = sp.GetRequiredService <IAzureAuthenticationService>(); var scopes = new List <string>() { "https://vault.azure.net/user_impersonation" }; return(await azureAuthenticationService.AuthenticateAsync(scopes.AsEnumerable())); })); return(keyVaultClient); }); serviceCollection.AddScoped <IAcmeHttpClient, AcmeHttpClient>((sp) => { var options = sp.GetRequiredService <IOptions <Settings> >(); var settings = options.Value; return(new AcmeHttpClient() { BaseAddress = new Uri(settings.LetsEncryptUri.AbsoluteUri) }); }); serviceCollection.AddScoped <IAzureAuthenticationService, AzureAuthenticationService>(); serviceCollection.AddScoped <IKeyVaultRepository, KeyVaultRepository>(); serviceCollection.AddScoped <ILetsEncryptRepository, LetsEncryptRepository>(); var serviceProvider = serviceCollection.BuildServiceProvider(); var keyVaultRepository = serviceProvider.GetRequiredService <IKeyVaultRepository>(); var letsEncryptRepository = serviceProvider.GetRequiredService <ILetsEncryptRepository>(); await keyVaultRepository.CreateSelfSignedCertificateAsync(selfSignedKeyVaultName, keyProperties, subjectName, subjectAlternativeNames, tags); var csr = await keyVaultRepository.CreateLetsEncryptCertificateAsync(letsEncryptedKeyVaultName, keyProperties, subjectName, subjectAlternativeNames, tags); var certificates = await letsEncryptRepository.IssueCertificateAsync(subjectAlternativeNames, csr); await keyVaultRepository.MergeCertificateAsync(letsEncryptedKeyVaultName, certificates); }
/// <summary> /// Loads all secrets which are delimited by : so that they can be retrieved by the config system /// Since KeyVault does not allow : as delimiters in the share secret name, the actual name is not used as key for configuration. /// The Tag property is used instead /// The tag should always be of the form "ConfigKey"="ParentKey1:Child1:.." /// </summary> /// <param name="token"></param> /// <returns></returns> private async Task LoadAsync(CancellationToken token) { string password; var cert = CertificateUtility.FindCertificateByThumbprint(_storeName, _storeLocation, _certificateThumbprint, _validateCertificate); var certBytes = CertificateUtility.ExportCertificateWithPrivateKey(cert, out password); _assertion = new ClientAssertionCertificate(_appClientId, certBytes, password); Data = new Dictionary<string, string>(); // This returns a list of identifiers which are uris to the secret, you need to use the identifier to get the actual secrets again. var kvClient = new KeyVaultClient(GetTokenAsync); var secretsResponseList = await kvClient.GetSecretsAsync(_vault, MaxSecrets, token); foreach (var secretItem in secretsResponseList.Value ?? new List<SecretItem>()) { //The actual config key is stored in a tag with the Key "ConfigKey" since : is not supported in a shared secret name by KeyVault if (secretItem.Tags != null && secretItem.Tags.ContainsKey(ConfigKey)) { var secret = await kvClient.GetSecretAsync(secretItem.Id, token); Data.Add(secret.Tags[ConfigKey], secret.Value); } } }
/// <summary>Initialize the secrets provider with the "keyVault" configuration section.</summary> /// <remarks> /// <para> /// Authentication using <see cref="LabAccessAuthenticationType.ClientCertificate"/> /// 1. Register Azure AD application of "Web app / API" type. /// To set up certificate based access to the application PowerShell should be used. /// 2. Add an access policy entry to target Key Vault instance for this application. /// /// The "keyVault" configuration section should define: /// "authType": "ClientCertificate" /// "clientId": [client ID] /// "certThumbprint": [certificate thumbprint] /// </para> /// <para> /// Authentication using <see cref="LabAccessAuthenticationType.UserCredential"/> /// 1. Register Azure AD application of "Native" type. /// 2. Add to 'Required permissions' access to 'Azure Key Vault (AzureKeyVault)' API. /// 3. When you run your native client application, it will automatically prompt user to enter Azure AD credentials. /// 4. To successfully access keys/secrets in the Key Vault, the user must have specific permissions to perform those operations. /// This could be achieved by directly adding an access policy entry to target Key Vault instance for this user /// or an access policy entry for an Azure AD security group of which this user is a member of. /// /// The "keyVault" configuration section should define: /// "authType": "UserCredential" /// "clientId": [client ID] /// </para> /// </remarks> public KeyVaultSecretsProvider() { _keyVaultClient = new KeyVaultClient(AuthenticationCallbackAsync); }
public async Task DeleteKeyAsync(string keyName) { await KeyVaultClient.DeleteKeyAsync(VaultAddress, keyName); }
private static KeyVaultClient GetKeyVaultClient(AzureServiceTokenProvider azureServiceTokenProvider) { var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); return(keyVaultClient); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { if (Environment.IsDevelopment()) { IdentityModelEventSource.ShowPII = true; services.AddMiniProfiler(); } var dapiKeysFileBlobStorageUri = Configuration["HAS:DataProtection:BlobStorageUri"]; var hasKeyVaultKeyIdentifier = Configuration["HAS:DataProtection:KeyIdentifier"]; var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback( azureServiceTokenProvider.KeyVaultTokenCallback)); services.AddDataProtection() .PersistKeysToAzureBlobStorage(new Uri(dapiKeysFileBlobStorageUri)) .ProtectKeysWithAzureKeyVault(keyVaultClient, hasKeyVaultKeyIdentifier); services.AddAutoMapper(typeof(Startup)); services.AddMediatR(typeof(Startup)); services.AddScoped <GatedRegistrationContext>(); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.AddHttpClient(); services.AddHttpClient(HASClientFactories.LIBRARY, client => { client.BaseAddress = new Uri(Configuration["MPY:API:Library:Authority"]); }); services.AddHttpClient(HASClientFactories.MEDIA, client => { client.BaseAddress = new Uri(Configuration["MPY:API:Media:Authority"]); }); services.AddHttpClient(HASClientFactories.PROFILE, client => { client.BaseAddress = new Uri(Configuration["MPY:API:Profile:Authority"]); }); services.AddHttpClient(HASClientFactories.TRIBE, client => { client.BaseAddress = new Uri(Configuration["MPY:API:Tribe:Authority"]); }); services.AddHttpClient(HASClientFactories.IDENTITY, client => { client.BaseAddress = new Uri(Configuration["MPY:IdentityServer:Authority"]); }); services.AddHttpClient(HASClientFactories.UPLOAD, client => { client.BaseAddress = new Uri(Configuration["MPY:API:Upload:Authority"]); }); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddHASIdentityService(Configuration, Environment); services.AddAuthorization(options => { options.AddPolicy("student", policyAdmin => policyAdmin.RequireClaim("role", "student")); options.AddPolicy("instructor", policyAdmin => policyAdmin.RequireClaim("role", "instructor")); options.AddPolicy("admin", policyAdmin => policyAdmin.RequireClaim("role", "admin")); options.AddPolicy("superadmin", policyAdmin => policyAdmin.RequireClaim("role", "superadmin")); }); services.AddHttpContextAccessor(); services.AddDistributedMemoryCache(); services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(120); options.Cookie.Name = Configuration["MPY:Cookies:Session:Name"]; options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); services.AddSingleton(new AuthMessageSenderOptions { SendGridKey = Configuration.GetSection("SendGrid:Key").Value, SendGridUser = Configuration.GetSection("SendGrid:User").Value }); services.AddTransient <IEmailSender, SendGridEmailSender>(); services.AddSingleton <IActionContextAccessor, ActionContextAccessor>(); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.AddHttpContextAccessor(); services.AddRazorPages(options => { options.Conventions.AuthorizeFolder("/Student", "student"); options.Conventions.AuthorizeFolder("/Admin", "admin"); options.Conventions.AuthorizeFolder("/Instructor", "instructor"); }) .AddRazorRuntimeCompilation() .AddFluentValidation(cfg => { cfg.RegisterValidatorsFromAssemblyContaining <Startup>(); }); }
private Task <X509Certificate2> CreateSelfSignedCertificateAndUploadAsync(KeyVaultClient client) { var certificate = CreateSelfSignedCertificateAndUpload(); return(ImportCertificateToKeyVaultAsync(client, certificate)); }
public static string GetConnString() { var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(KeyVaultUtil.GetToken)); string conn = kv.GetSecretAsync(WebConfigurationManager.AppSettings["SecretUri"]).Result.Value; return conn; }
private async Task KeysMigrationGuide() { #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_Create AzureServiceTokenProvider provider = new AzureServiceTokenProvider(); KeyVaultClient client = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback)); #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_Create #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_CreateWithOptions using (HttpClient httpClient = new HttpClient()) { //@@AzureServiceTokenProvider provider = new AzureServiceTokenProvider(); /*@@*/ provider = new AzureServiceTokenProvider(); //@@KeyVaultClient client = new KeyVaultClient( /*@@*/ client = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback), httpClient); } #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_CreateWithOptions { #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_CreateKey // Create RSA key. NewKeyParameters createRsaParameters = new NewKeyParameters { Kty = JsonWebKeyType.Rsa, KeySize = 4096 }; KeyBundle rsaKey = await client.CreateKeyAsync("https://myvault.vault.azure.net", "rsa-key-name", createRsaParameters); // Create Elliptic-Curve key. NewKeyParameters createEcParameters = new NewKeyParameters { Kty = JsonWebKeyType.EllipticCurve, CurveName = "P-256" }; KeyBundle ecKey = await client.CreateKeyAsync("https://myvault.vault.azure.net", "ec-key-name", createEcParameters); #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_CreateKey } { #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_ListKeys IPage <KeyItem> page = await client.GetKeysAsync("https://myvault.vault.azure.net"); foreach (KeyItem item in page) { KeyIdentifier keyId = item.Identifier; KeyBundle key = await client.GetKeyAsync(keyId.Vault, keyId.Name); } while (page.NextPageLink != null) { page = await client.GetKeysNextAsync(page.NextPageLink); foreach (KeyItem item in page) { KeyIdentifier keyId = item.Identifier; KeyBundle key = await client.GetKeyAsync(keyId.Vault, keyId.Name); } } #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_ListKeys } { #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_DeleteKey // Delete the key. DeletedKeyBundle deletedKey = await client.DeleteKeyAsync("https://myvault.vault.azure.net", "key-name"); // Purge or recover the deleted key if soft delete is enabled. if (deletedKey.RecoveryId != null) { DeletedKeyIdentifier deletedKeyId = deletedKey.RecoveryIdentifier; // Deleting a key does not happen immediately. Wait a while and check if the deleted key exists. while (true) { try { await client.GetDeletedKeyAsync(deletedKeyId.Vault, deletedKeyId.Name); // Finally deleted. break; } catch (KeyVaultErrorException ex) when(ex.Response.StatusCode == HttpStatusCode.NotFound) { // Not yet deleted... } } // Purge the deleted key. await client.PurgeDeletedKeyAsync(deletedKeyId.Vault, deletedKeyId.Name); // You can also recover the deleted key using RecoverDeletedKeyAsync. } #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_DeleteKey } { #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_Encrypt // Encrypt a message. The plaintext must be small enough for the chosen algorithm. byte[] plaintext = Encoding.UTF8.GetBytes("Small message to encrypt"); KeyOperationResult encrypted = await client.EncryptAsync("rsa-key-name", JsonWebKeyEncryptionAlgorithm.RSAOAEP256, plaintext); // Decrypt the message. KeyOperationResult decrypted = await client.DecryptAsync("rsa-key-name", JsonWebKeyEncryptionAlgorithm.RSAOAEP256, encrypted.Result); string message = Encoding.UTF8.GetString(decrypted.Result); #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_Encrypt } { #region Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_Wrap using (Aes aes = Aes.Create()) { // Use a symmetric key to encrypt large amounts of data, possibly streamed... // Now wrap the key and store the encrypted key and plaintext IV to later decrypt the key to decrypt the data. KeyOperationResult wrapped = await client.WrapKeyAsync( "https://myvault.vault.azure.net", "rsa-key-name", null, JsonWebKeyEncryptionAlgorithm.RSAOAEP256, aes.Key); // Read the IV and the encrypted key from the payload, then unwrap the key. KeyOperationResult unwrapped = await client.UnwrapKeyAsync( "https://myvault.vault.azure.net", "rsa-key-name", null, JsonWebKeyEncryptionAlgorithm.RSAOAEP256, wrapped.Result); aes.Key = unwrapped.Result; // Decrypt the payload with the symmetric key. } #endregion Snippet:Microsoft_Azure_KeyVault_Keys_Snippets_MigrationGuide_Wrap } }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log) { string secretValue = string.Empty; log.LogInformation("GetKeyVaultSecret Function is called"); try { //Get secret Name from the query string string secretName = req.Query["SecretName"]; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); secretName = secretName ?? data?.SecretName; if (!string.IsNullOrEmpty(secretName)) { log.LogInformation("Secret Vaule Requested For : " + secretName); //Create new service token provider using System Assigned Managed Identity AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); //Create new Key Vault Client KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); //Get Key Vault Name from application configuration string keyVaultName = ConstantsHelper.GetEnvironmentVariable(ConstantsHelper.keyVaultName); log.LogInformation("Fetching Details from KeyVault : " + keyVaultName); //Fetching the Key Vault URI string keyVaultUri = String.Format(Convert.ToString(ConstantsHelper.keyVaultUri), keyVaultName); log.LogInformation("KeyVaultUri : " + keyVaultUri); //Get secret from Key Vault SecretBundle secretBundle = await keyVaultClient.GetSecretAsync(keyVaultUri, secretName); if (secretBundle != null) { //Get Secret Value to be returned secretValue = secretBundle.Value; log.LogInformation("Details are fetched from KeyVault"); return(new OkObjectResult(secretValue)); } else { log.LogInformation("No such key name present in KeyVault"); //Return no key found message return(new NotFoundObjectResult("No such key name present in KeyVault")); } } else { log.LogInformation("secretName is missing in request"); return(new BadRequestObjectResult("secretName is missing in request")); } } catch (Exception ex) { log.LogInformation($"GetKeyVaultSecret got an exception \n Time: { DateTime.Now} \n Exception{ ex.Message}"); return(new NotFoundObjectResult($"\n GetKeyVaultSecret got an exception \n Time: { DateTime.Now} \n Exception{ ex.Message}")); } }
public override async Task <ActionResponse> ExecuteActionAsync(ActionRequest request) { string azureToken = request.DataStore.GetJson("AzureTokenKV", "access_token"); string refreshToken = request.DataStore.GetJson("AzureTokenKV", "refresh_token"); string crmToken = request.DataStore.GetJson("MsCrmToken", "access_token"); string resourceGroup = request.DataStore.GetValue("SelectedResourceGroup"); string vaultName = request.DataStore.GetValue("VaultName") ?? "bpstv-" + RandomGenerator.GetRandomLowerCaseCharacters(12); string secretName = request.DataStore.GetValue("SecretName") ?? "bpst-mscrm-secret"; string connectionString = request.DataStore.GetAllValues("SqlConnectionString")[0]; string organizationId = request.DataStore.GetValue("OrganizationId"); _subscriptionId = request.DataStore.GetJson("SelectedSubscription", "SubscriptionId"); RetrieveKVToken(refreshToken, request.Info.WebsiteRootUrl, request.DataStore); RetrieveGraphToken(refreshToken, request.Info.WebsiteRootUrl, request.DataStore); SubscriptionCloudCredentials credentials = new TokenCloudCredentials(_subscriptionId, azureToken); // Get user's object ID and tenant ID (in the Azure subscription where the vault is created) string oid = null; int propCount = 0; foreach (var c in new JwtSecurityToken(azureToken).Claims) { switch (c.Type.ToLowerInvariant()) { case "oid": oid = c.Value; propCount++; break; case "tid": _tenantId = c.Value; propCount++; break; } if (propCount >= 2) { break; } } // Get user's tenant ID in the CRM implicit subscription string crmtenantId = null; foreach (var c in new JwtSecurityToken(crmToken).Claims) { if (c.Type.EqualsIgnoreCase("tid")) { crmtenantId = c.Value; break; } } try { TokenCredentials credentialsKv = new TokenCredentials(azureToken); using (KeyVaultManagementClient client = new KeyVaultManagementClient(credentialsKv)) { client.SubscriptionId = _subscriptionId; // Check if a vault already exists var vaults = client.Vaults.ListByResourceGroup(resourceGroup); foreach (var v in client.Vaults.ListByResourceGroup(resourceGroup)) { if (v.Name.EqualsIgnoreCase(vaultName)) { client.Vaults.Delete(resourceGroup, vaultName); break; } } // Create the vault string vaultUrl = null; using (ResourceManagementClient resourceClient = new ResourceManagementClient(credentials)) { // Set properties VaultProperties p = new VaultProperties() { Sku = new Sku(SkuName.Standard), TenantId = new Guid(_tenantId), AccessPolicies = new List <AccessPolicyEntry>() }; // Access policy for the owner AccessPolicyEntry apeOwner = new AccessPolicyEntry(); apeOwner.Permissions = new Permissions(new[] { "get", "create", "delete", "list", "update", "import", "backup", "restore" }, new[] { "all" }, new[] { "all" }); apeOwner.TenantId = p.TenantId; apeOwner.ObjectId = oid; p.AccessPolicies.Add(apeOwner); // Access policy for the CRM exporter AccessPolicyEntry ape = new AccessPolicyEntry(); ape.Permissions = new Permissions(null, new[] { "get" }); ape.TenantId = p.TenantId; ape.ObjectId = GetCrmConnectorObjectID(_graphToken, _tenantId).Result; p.AccessPolicies.Add(ape); VaultCreateOrUpdateParameters vaultParams = new VaultCreateOrUpdateParameters() { Location = resourceClient.ResourceGroups.Get(resourceGroup).ResourceGroup.Location, Properties = p }; Vault vault = client.Vaults.CreateOrUpdate(resourceGroup, vaultName, vaultParams); vaultUrl = vault.Properties.VaultUri; Thread.Sleep(15000); // The vault DNS entry isn't there immediatly } // Create the secret KeyVaultClient kvClient = new KeyVaultClient(new TokenCredentials(_kvToken)); SecretBundle secret = await kvClient.SetSecretAsync(vaultUrl, secretName, connectionString, new Dictionary <string, string>() { { organizationId, crmtenantId } }, null /* Do I need to set a content type? */, new SecretAttributes() { Enabled = true }); request.DataStore.AddToDataStore("KeyVault", secret.Id, DataStoreType.Private); } } catch (Exception) { throw; } return(new ActionResponse(ActionStatus.Success, JsonUtility.GetEmptyJObject(), true)); }
public SecretManager(KeyVaultClient client) { this.client = client; }
/// <summary> /// Adds the KeyVaultConnection to services via DI /// </summary> /// <param name="services">IServiceCollection</param> /// <param name="client">KeyVaultClient</param> /// <param name="uri">Key Vault URI</param> /// <returns>IServiceCollection</returns> public static IServiceCollection AddKeyVaultConnection(this IServiceCollection services, KeyVaultClient client, Uri uri) { // add the KeyVaultConnection as a singleton services.AddSingleton <IKeyVaultConnection>(new KeyVaultConnection { Client = client, Uri = uri }); return(services); }
public static async Task <string> GetVaultKeyValueAsync() { var appKeyValue = string.Empty; var Message = ""; int retries = 0; bool retry = false; try { /* The below 4 lines of code shows you how to use AppAuthentication library to fetch secrets from your Key Vault*/ AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); var secret = await keyVaultClient.GetSecretAsync("https://keyvault1000.vault.azure.net/secrets/AppKey") .ConfigureAwait(false); appKeyValue = secret.Value; /* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/ do { long waitTime = Math.Min(getWaitTime(retries), 2000000); secret = await keyVaultClient.GetSecretAsync("https://keyvault1000.vault.azure.net/secrets/AppKey") .ConfigureAwait(false); retry = false; }while (retry && (retries++ < 10)); } /// <exception cref="KeyVaultErrorException"> /// Thrown when the operation returned an invalid status code /// </exception> catch (KeyVaultErrorException keyVaultException) { Message = keyVaultException.Message; if ((int)keyVaultException.Response.StatusCode == 429) { retry = true; } } return(appKeyValue); #region short code //try //{ ///* The below 4 lines of code shows you how to use AppAuthentication library to fetch secrets from your Key Vault*/ //AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); //KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); //var secret = await keyVaultClient.GetSecretAsync("https://keyvault1000.vault.azure.net/secrets/AppKey") ////var secret = await keyVaultClient.GetSecretAsync("https://keyvault1000.vault.azure.net/secrets/AppKey/XXXXX") ////var secret = await keyVaultClient.GetSecretAsync("https://<YourKeyVaultName>.vault.azure.net/secrets/AppSecret") // .ConfigureAwait(true); // //.ConfigureAwait(false); //return secret.Value; // //Message = secret.Value; //} //catch (Exception ex) //{ // var msg = ex.Message; // throw; //} #endregion }
public void ConfigureServices(IServiceCollection services) { services.AddSingleton <ILocalizationProvider, StorageLocalizationProvider>(); services.AddTextLocalization(options => { options.ReturnOnlyKeyIfNotFound = !_environment.IsDevelopment(); options.FallBackNeutralCulture = !_environment.IsDevelopment(); }).Configure <RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture(Settings.SupportedCultures[0]); options.AddSupportedCultures(Settings.SupportedCultures); options.AddSupportedUICultures(Settings.SupportedCultures); }); var dataProtectionBuilder = services.AddDataProtection().SetApplicationName(projectName); services.RegisterStorage(Configuration); services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); services.AddIdentity <ApplicationUser, ApplicationRole>() .AddRoles <ApplicationRole>() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders() .AddErrorDescriber <LocalizedIdentityErrorDescriber>(); services.AddScoped <IUserClaimsPrincipalFactory <ApplicationUser>, AdditionalUserClaimsPrincipalFactory>(); var authAuthority = Configuration[$"{projectName}:IS4ApplicationUrl"].TrimEnd('/'); // Adds IdentityServer https://identityserver4.readthedocs.io/en/latest/reference/options.html var identityServerBuilder = services.AddIdentityServer(options => { options.IssuerUri = authAuthority; options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; options.UserInteraction.ErrorUrl = "/identityserver/error"; }) .AddIdentityServerStores(Configuration) .AddAspNetIdentity <ApplicationUser>(); //https://identityserver4.readthedocs.io/en/latest/reference/aspnet_identity.html X509Certificate2 cert = null; var keysFolder = Path.Combine(_environment.ContentRootPath, "Keys"); if (_environment.IsDevelopment()) { // The AddDeveloperSigningCredential extension creates temporary key material tempkey.jwk for signing tokens. // This might be useful to get started, but needs to be replaced by some persistent key material for production scenarios. // See http://docs.identityserver.io/en/release/topics/crypto.html#refcrypto for more information. // https://stackoverflow.com/questions/42351274/identityserver4-hosting-in-iis identityServerBuilder.AddDeveloperSigningCredential(); dataProtectionBuilder.PersistKeysToFileSystem(new DirectoryInfo(keysFolder)); } else { // running on azure // please make sure to replace your vault URI and your certificate name in appsettings.json! if (Convert.ToBoolean(Configuration["HostingOnAzure:RunsOnAzure"]) == true) { // if we use a key vault if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UsingKeyVault"]) == true) { //https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview dataProtectionBuilder.PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>")) .ProtectKeysWithAzureKeyVault("<keyIdentifier>", "<clientId>", "<clientSecret>"); // if managed app identity is used if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UseManagedAppIdentity"]) == true) { AzureServiceTokenProvider azureServiceTokenProvider = new(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); var certificateBundle = keyVaultClient.GetSecretAsync(Configuration["HostingOnAzure:AzureKeyVault:VaultURI"], Configuration["HostingOnAzure:AzurekeyVault:CertificateName"]).GetAwaiter().GetResult(); var certificate = Convert.FromBase64String(certificateBundle.Value); cert = new X509Certificate2(certificate, (string)null, X509KeyStorageFlags.MachineKeySet); } } else // if app id and app secret are used { throw new NotImplementedException(); } } else { dataProtectionBuilder.PersistKeysToFileSystem(new DirectoryInfo(keysFolder)); } //TODO this implementation does not consider certificate expiration if (Convert.ToBoolean(Configuration[$"{projectName}:UseLocalCertStore"]) == true) { var certificateThumbprint = Configuration[$"{projectName}:CertificateThumbprint"]; var storeLocation = StoreLocation.LocalMachine; dynamic storeName = "WebHosting"; if (OperatingSystem.IsLinux()) { storeLocation = StoreLocation.CurrentUser; storeName = StoreName.My; } using X509Store store = new(storeName, storeLocation); store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); if (certs.Count > 0) { cert = certs[0]; } else { var certPath = Path.Combine(_environment.ContentRootPath, "AuthSample.pfx"); if (File.Exists(certPath)) { string certificatePassword = Configuration[$"{projectName}:CertificatePassword"] ?? "Admin123"; cert = new X509Certificate2(certPath, certificatePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); } } store.Close(); } // pass the resulting certificate to Identity Server if (cert != null) { identityServerBuilder.AddSigningCredential(cert); Log.Logger.Information($"Added certificate {cert.Subject} to Identity Server"); } else if (OperatingSystem.IsWindows()) { Log.Logger.Debug("Trying to use WebHosting Certificate for Identity Server"); identityServerBuilder.AddWebHostingCertificate(); } else { throw new Exception("Missing Certificate for Identity Server"); } } var authBuilder = services.AddAuthentication(options => { options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(options => { options.Authority = authAuthority; options.SupportedTokens = SupportedTokens.Jwt; options.RequireHttpsMetadata = _environment.IsProduction(); options.ApiName = IdentityServerConfig.LocalApiName; options.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; // If the request is for our hub... var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/chathub"))) { // Read the token out of the query string context.Token = accessToken; } return(Task.CompletedTask); } }; }); #region ExternalAuthProviders //https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/samples/SocialSample/Startup.cs //https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Google:Enabled"] ?? "false")) { authBuilder.AddGoogle(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Google:ClientId"]; options.ClientSecret = Configuration["ExternalAuthProviders:Google:ClientSecret"]; options.AuthorizationEndpoint += "?prompt=consent"; // Hack so we always get a refresh token, it only comes on the first authorization response options.AccessType = "offline"; options.SaveTokens = true; options.Events = new OAuthEvents() { OnRemoteFailure = HandleOnRemoteFailure }; options.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url"); options.ClaimActions.Remove(ClaimTypes.GivenName); }); } if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Facebook:Enabled"] ?? "false")) { // You must first create an app with Facebook and add its ID and Secret to your user-secrets. // https://developers.facebook.com/apps/ // https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#login authBuilder.AddFacebook(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.AppId = Configuration["ExternalAuthProviders:Facebook:AppId"]; options.AppSecret = Configuration["ExternalAuthProviders:Facebook:AppSecret"]; options.Scope.Add("email"); options.Fields.Add("name"); options.Fields.Add("email"); options.SaveTokens = true; options.Events = new OAuthEvents() { OnRemoteFailure = HandleOnRemoteFailure }; }); } if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Twitter:Enabled"] ?? "false")) { // You must first create an app with Twitter and add its key and Secret to your user-secrets. // https://apps.twitter.com/ // https://developer.twitter.com/en/docs/basics/authentication/api-reference/access_token authBuilder.AddTwitter(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ConsumerKey = Configuration["ExternalAuthProviders:Twitter:ConsumerKey"]; options.ConsumerSecret = Configuration["ExternalAuthProviders:Twitter:ConsumerSecret"]; // http://stackoverflow.com/questions/22627083/can-we-get-email-id-from-twitter-oauth-api/32852370#32852370 // http://stackoverflow.com/questions/36330675/get-users-email-from-twitter-api-for-external-login-authentication-asp-net-mvc?lq=1 options.RetrieveUserDetails = true; options.SaveTokens = true; options.ClaimActions.MapJsonKey("urn:twitter:profilepicture", "profile_image_url", ClaimTypes.Uri); options.Events = new TwitterEvents() { OnRemoteFailure = HandleOnRemoteFailure }; }); } //https://github.com/xamarin/Essentials/blob/master/Samples/Sample.Server.WebAuthenticator/Startup.cs if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Apple:Enabled"] ?? "false")) { authBuilder.AddApple(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Apple:ClientId"]; options.KeyId = Configuration["ExternalAuthProviders:Apple:KeyId"]; options.TeamId = Configuration["ExternalAuthProviders:Apple:TeamId"]; options.UsePrivateKey(keyId => _environment.ContentRootFileProvider.GetFileInfo($"AuthKey_{keyId}.p8")); options.SaveTokens = true; }); } // You must first create an app with Microsoft Account and add its ID and Secret to your user-secrets. // https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Microsoft:Enabled"] ?? "false")) { authBuilder.AddMicrosoftAccount(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Microsoft:ClientId"]; options.ClientSecret = Configuration["ExternalAuthProviders:Microsoft:ClientSecret"]; options.SaveTokens = true; options.Scope.Add("offline_access"); options.Events = new OAuthEvents() { OnRemoteFailure = HandleOnRemoteFailure }; }); } #endregion #region Authorization //Add Policies / Claims / Authorization - https://identityserver4.readthedocs.io/en/latest/topics/add_apis.html#advanced services.AddScoped <EntityPermissions>(); services.AddSingleton <IAuthorizationPolicyProvider, AuthorizationPolicyProvider>(); services.AddTransient <IAuthorizationHandler, DomainRequirementHandler>(); services.AddTransient <IAuthorizationHandler, PermissionRequirementHandler>(); #endregion services.Configure <IdentityOptions>(options => { // Password settings options.Password.RequireDigit = RequireDigit; options.Password.RequiredLength = RequiredLength; options.Password.RequireNonAlphanumeric = RequireNonAlphanumeric; options.Password.RequireUppercase = RequireUppercase; options.Password.RequireLowercase = RequireLowercase; //options.Password.RequiredUniqueChars = 6; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; options.Lockout.AllowedForNewUsers = true; // Require Confirmed Email User settings if (Convert.ToBoolean(Configuration[$"{projectName}:RequireConfirmedEmail"] ?? "false")) { options.User.RequireUniqueEmail = true; options.SignIn.RequireConfirmedEmail = true; } }); #region Cookies // cookie policy to deal with temporary browser incompatibilities services.AddSameSiteCookiePolicy(); //https://docs.microsoft.com/en-us/aspnet/core/security/gdpr services.Configure <CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential // cookies is needed for a given request. options.CheckConsentNeeded = context => false; //consent not required // requires using Microsoft.AspNetCore.Http; //options.MinimumSameSitePolicy = SameSiteMode.None; }); //services.ConfigureExternalCookie(options => // { // macOS login fix //options.Cookie.SameSite = SameSiteMode.None; //}); services.ConfigureApplicationCookie(options => { options.Cookie.IsEssential = true; options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.LoginPath = Constants.Settings.LoginPath; //options.AccessDeniedPath = "/Identity/Account/AccessDenied"; // ReturnUrlParameter requires //using Microsoft.AspNetCore.Authentication.Cookies; options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; options.SlidingExpiration = true; // Suppress redirect on API URLs in ASP.NET Core -> https://stackoverflow.com/a/56384729/54159 options.Events = new CookieAuthenticationEvents() { OnRedirectToAccessDenied = context => { if (context.Request.Path.StartsWithSegments("/api")) { context.Response.StatusCode = Status403Forbidden; } return(Task.CompletedTask); }, OnRedirectToLogin = context => { context.Response.StatusCode = Status401Unauthorized; return(Task.CompletedTask); } }; }); #endregion services.AddMvc().AddNewtonsoftJson(opt => { // Set Breeze defaults for entity serialization var ss = JsonSerializationFns.UpdateWithDefaults(opt.SerializerSettings); if (ss.ContractResolver is DefaultContractResolver resolver) { resolver.NamingStrategy = null; // remove json camelCasing; names are converted on the client. } if (_environment.IsDevelopment()) { ss.Formatting = Newtonsoft.Json.Formatting.Indented; // format JSON for debugging } }) // Add Breeze exception filter to send errors back to the client .AddMvcOptions(o => { o.Filters.Add(new GlobalExceptionFilter()); }) .AddViewLocalization().AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => { return(factory.Create(typeof(Global))); }; }).AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining <LocalizationRecordValidator>()); services.AddServerSideBlazor().AddCircuitOptions(o => { if (_environment.IsDevelopment()) { o.DetailedErrors = true; } }).AddHubOptions(o => { o.MaximumReceiveMessageSize = 131072; }); services.AddSignalR(); if (_enableAPIDoc) { services.AddOpenApiDocument(document => { document.Title = "BlazorBoilerplate API"; document.Version = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString(); document.AddSecurity("bearer", Enumerable.Empty <string>(), new OpenApiSecurityScheme { Type = OpenApiSecuritySchemeType.OAuth2, Description = "Local Identity Server", OpenIdConnectUrl = $"{authAuthority}/.well-known/openid-configuration", //not working Flow = OpenApiOAuth2Flow.AccessCode, Flows = new OpenApiOAuthFlows() { AuthorizationCode = new OpenApiOAuthFlow() { Scopes = new Dictionary <string, string> { { LocalApi.ScopeName, IdentityServerConfig.LocalApiName } }, AuthorizationUrl = $"{authAuthority}/connect/authorize", TokenUrl = $"{authAuthority}/connect/token" }, } });; document.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("bearer")); // new OperationSecurityScopeProcessor("bearer")); }); } services.AddScoped <IUserSession, UserSession>(); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.Add(ServiceDescriptor.Scoped(typeof(ITenantSettings <>), typeof(TenantSettingsManager <>))); services.AddTransient <IEmailFactory, EmailFactory>(); services.AddTransient <IAccountManager, AccountManager>(); services.AddTransient <IAdminManager, AdminManager>(); services.AddTransient <IEmailManager, EmailManager>(); services.AddTransient <IExternalAuthManager, ExternalAuthManager>(); #region Automapper //Automapper to map DTO to Models https://www.c-sharpcorner.com/UploadFile/1492b1/crud-operations-using-automapper-in-mvc-application/ var automapperConfig = new MapperConfiguration(configuration => { configuration.AddProfile(new MappingProfile()); }); var autoMapper = automapperConfig.CreateMapper(); services.AddSingleton(autoMapper); #endregion /* ServerSideBlazor */ services.AddScoped <IAccountApiClient, AccountApiClient>(); services.AddScoped <AppState>(); // setup HttpClient for server side in a client side compatible fashion ( with auth cookie ) // if (!services.Any(x => x.ServiceType == typeof(HttpClient))) // { services.AddScoped(s => { // creating the URI helper needs to wait until the JS Runtime is initialized, so defer it. var navigationManager = s.GetRequiredService <NavigationManager>(); var httpContextAccessor = s.GetRequiredService <IHttpContextAccessor>(); var cookies = httpContextAccessor.HttpContext.Request.Cookies; var httpClientHandler = new HttpClientHandler() { UseCookies = false }; if (_environment.IsDevelopment()) { // Return 'true' to allow certificates that are untrusted/invalid httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return(true); }; } var client = new HttpClient(httpClientHandler); if (cookies.Any()) { var cks = new List <string>(); foreach (var cookie in cookies) { cks.Add($"{cookie.Key}={cookie.Value}"); } client.DefaultRequestHeaders.Add("Cookie", string.Join(';', cks)); } client.BaseAddress = new Uri(navigationManager.BaseUri); return(client); }); // } services.AddScoped <ILocalizationApiClient, LocalizationApiClient>(); services.AddScoped <IApiClient, ApiClient>(); // Authentication providers Log.Logger.Debug("Removing AuthenticationStateProvider..."); var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(AuthenticationStateProvider)); if (serviceDescriptor != null) { services.Remove(serviceDescriptor); } Log.Logger.Debug("Adding AuthenticationStateProvider..."); services.AddScoped <AuthenticationStateProvider, IdentityAuthenticationStateProvider>(); /**********************/ services.AddModules(); if (Log.Logger.IsEnabled(Serilog.Events.LogEventLevel.Debug)) { Log.Logger.Debug($"Total Services Registered: {services.Count}"); foreach (var service in services) { Log.Logger.Debug($"\n\tService: {service.ServiceType.FullName}\n\tLifetime: {service.Lifetime}\n\tInstance: {service.ImplementationType?.FullName}"); } } }
public static async System.Threading.Tasks.Task RunAsync([BlobTrigger("videos/{name}", Connection = "wmvideostorage")] Stream myBlob, string name, TraceWriter log) { // Grab Api Key for Video Indexer: https://medium.com/statuscode/getting-key-vault-secrets-in-azure-functions-37620fd20a0b var azureServiceTokenProvider = new AzureServiceTokenProvider(); var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback), kvhttpClient); string videoindexerKey = (await kvClient.GetSecretAsync(Environment.GetEnvironmentVariable("wm-videoindexer-key"))).Value; var accountId = (await kvClient.GetSecretAsync(Environment.GetEnvironmentVariable("wm-videoindexer-accountid"))).Value; // Upload video from blob storage to Video Indexer var handler = new HttpClientHandler(); handler.AllowAutoRedirect = false; var viClient = new HttpClient(handler); viClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", videoindexerKey); var apiUrl = "https://api.videoindexer.ai"; var location = "trial"; // Get Auth Token for Account var accountAccessTokenRequestResult = viClient.GetAsync($"{apiUrl}/auth/{location}/Accounts/{accountId}/AccessToken?allowEdit=true").Result; var accountAccessToken = accountAccessTokenRequestResult.Content.ReadAsStringAsync().Result.Replace("\"", ""); // Remove API Key for operation calls viClient.DefaultRequestHeaders.Remove("Ocp-Apim-Subscription-Key"); // Use the stream blob for the Multipart upload var content = new MultipartFormDataContent(); content.Add(new StreamContent(myBlob), "Video", name); var result = viClient.PostAsync($"{apiUrl}/{location}/Accounts/{accountId}/Videos?accessToken={accountAccessToken}&name={name}&privacy=private", content).Result; var json = result.Content.ReadAsStringAsync().Result; // Set variables for Cosmosdb Object var myVideoUploadStatus = JsonConvert.DeserializeObject <videoIndexData>(json); myVideoUploadStatus.state = "Processing"; myVideoUploadStatus.blobPath = $"/videos/{name}"; log.Info($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes\nBreakdownId:{myVideoUploadStatus.id}"); // Connect to Cosmos Db CosmosDBHelper.AccessKey = (await kvClient.GetSecretAsync(Environment.GetEnvironmentVariable("wm-cosmosdb-key"))).Value; CosmosDBHelper.EndpointUri = (await kvClient.GetSecretAsync(Environment.GetEnvironmentVariable("wm-cosmosdb-uri"))).Value; CosmosDBHelper.DatabaseName = "wm-videos"; CosmosDBHelper.CollectionName = "videos"; cosmosDb = await CosmosDBHelper.BuildAsync(); log.Info("Connected to CosmosDb.."); // Write to Cosmos DbW try { var existing = await cosmosDb.FindDocumentByIdAsync <videoIndexData>(myVideoUploadStatus.id); if (existing == null) { log.Info($"id {myVideoUploadStatus.id} does not exist in CosmosDb. Creating new record.."); await cosmosDb.CreateDocumentIfNotExistsAsync(myVideoUploadStatus, myVideoUploadStatus.id); } else { log.Info($"id {myVideoUploadStatus.id} already exists in CosmosDb. Attempting an update.."); await cosmosDb.UpdateDocumentAsync(myVideoUploadStatus, myVideoUploadStatus.id); } } catch (Exception e) { log.Info($"Exception caught:{e}"); } }
public VaultBase() { VaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken)); AzureVaultAddress = $"https://{ConfigHelper.GetString("KeyVault.VaultName")}.vault.azure.net/";; }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "books/{bookId}")] HttpRequestMessage req, string bookid, ExecutionContext context, ILogger log) { log.LogInformation("C# HTTP trigger function to delete book by id."); var config = new ConfigurationBuilder() .SetBasePath(context.FunctionAppDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); //apply for key vault client var serviceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(serviceTokenProvider.KeyVaultTokenCallback)); IQueryable <Book> bookQuery; //storage variables for secrets SecretBundle secrets; String cosmosEndpointUrl = String.Empty; String cosmosAuthorizationKey = String.Empty; String database = String.Empty; String collection = String.Empty; // Connect to vault client try { secrets = await keyVaultClient.GetSecretAsync($"{config["KEY_VAULT_URI"]}secrets/{config["COSMOS_NAME"]}/"); //parse json stored. JObject details = JObject.Parse(secrets.Value.ToString()); cosmosEndpointUrl = (string)details["COSMOS_URI"]; cosmosAuthorizationKey = (string)details["COSMOS_KEY"]; database = (string)details["COSMOS_DB"]; collection = (string)details["COSMOS_COLLECTION"]; } catch (KeyVaultErrorException ex) { return(new ForbidResult("Unable to access secrets in vault!" + ex.Message)); } //set options client and query FeedOptions queryOptions = new FeedOptions { EnableCrossPartitionQuery = true }; DocumentClient client = new DocumentClient(new Uri(cosmosEndpointUrl), cosmosAuthorizationKey); try { bookQuery = client.CreateDocumentQuery <Book>(UriFactory.CreateDocumentCollectionUri(database, collection), "SELECT * FROM Books b WHERE b.id = \'" + bookid + "\'", queryOptions); List <Book> bookList = bookQuery.ToList <Book>(); if (bookList.Count == 0) { log.LogInformation("Book not found."); return((ActionResult) new StatusCodeResult(404)); } foreach (var book in bookList) { Uri docUri = UriFactory.CreateDocumentUri(database, collection, book.Id); // Need to provide the partitionKey here // The key can by found from database > collection > scale and settings partition key // The partition key is: /title await client.DeleteDocumentAsync(docUri, new RequestOptions { PartitionKey = new PartitionKey(book.Title) }); Console.WriteLine(@"Deleted: {0}", book.Id); } } catch (Exception ex) { log.LogError("Unable to delete book: " + ex.Message); return((ActionResult) new StatusCodeResult(500)); } return((ActionResult) new OkObjectResult("Successfully deleted bookId : " + bookid)); }
public KeyVaultCredential(KeyVaultClient.AuthenticationCallback authenticationCallback) { OnAuthenticate = authenticationCallback; }
public static async Task <Result <Monitor> > CreateAsync(OperationContext context, Configuration configuration) { Tracer.Info(context, "Creating Kusto ingest client"); var kustoIngestClient = ExternalDependenciesFactory.CreateKustoIngestClient( configuration.KustoIngestionClusterUrl, configuration.AzureTenantId, configuration.AzureAppId, configuration.AzureAppKey).ThrowIfFailure(); Tracer.Info(context, "Creating Kusto query client"); var kustoClient = ExternalDependenciesFactory.CreateKustoQueryClient( configuration.KustoClusterUrl, configuration.AzureTenantId, configuration.AzureAppId, configuration.AzureAppKey).ThrowIfFailure(); IIcmClient icmClient; if (!configuration.ReadOnly) { Tracer.Info(context, "Creating KeyVault client"); var keyVaultClient = new KeyVaultClient( configuration.KeyVaultUrl, configuration.AzureTenantId, configuration.AzureAppId, configuration.AzureAppKey, SystemClock.Instance, Constants.IcmCertificateCacheTimeToLive); Tracer.Info(context, "Creating IcM client"); icmClient = new IcmClient( keyVaultClient, configuration.IcmUrl, configuration.IcmConnectorId, configuration.IcmCertificateName); } else { Tracer.Info(context, "Using mock ICM client"); icmClient = new MockIcmClient(); } var environmentResources = new Dictionary <CloudBuildEnvironment, EnvironmentResources>(); // This does a bunch of Azure API calls, which are really slow. Making them a bit faster by doing them // concurrently. await configuration.Environments.ParallelForEachAsync(async (keyValuePair) => { var environment = keyValuePair.Key; var environmentConfiguration = keyValuePair.Value; Tracer.Info(context, $"Loading resources for environment `{environment}`"); var resources = await CreateEnvironmentResourcesAsync(context, configuration, environmentConfiguration); lock (environmentResources) { environmentResources[environment] = resources; } }); context.Token.ThrowIfCancellationRequested(); return(new Monitor(configuration, kustoIngestClient, kustoClient, icmClient, SystemClock.Instance, environmentResources, context.TracingContext.Logger)); }
private async Task CreateKey() { var kv = new KeyVaultClient(GetAccessTokenAsync, new HttpClient()); kv.CreateKeyAsync(this.KeyVaultAddress, "Siva", ""); }
public async Task <bool> Verify(string keyId, byte[] hash, byte[] signature) { var result = await KeyVaultClient.VerifyAsync(keyId, "RS256", hash, signature); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="KeyVaultSecretAccessor"/> class. /// This constructor is introduced to increase testability /// </summary> public KeyVaultSecretAccessor(IAadAccessTokenHandler aadAccessTokenHandler) { _aadAccessTokenHandler = aadAccessTokenHandler; _keyVaultClient = new KeyVaultClient(_aadAccessTokenHandler.GetAccessTokenAsync); _secretValidator = new KeyVaultSecretValidator(); }
public async Task <byte[]> Sign(string keyId, byte[] hash) { var bundle = await KeyVaultClient.SignAsync(keyId, "RS256", hash); return(bundle.Result); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; var useSqlServer = Convert.ToBoolean(Configuration["BlazorBoilerplate:UseSqlServer"] ?? "false"); var dbConnString = useSqlServer ? Configuration.GetConnectionString("DefaultConnection") : $"Filename={Configuration.GetConnectionString("SqlLiteConnectionFileName")}"; var authAuthority = Configuration["BlazorBoilerplate:IS4ApplicationUrl"].TrimEnd('/'); void DbContextOptionsBuilder(DbContextOptionsBuilder builder) { if (useSqlServer) { builder.UseSqlServer(dbConnString, sql => sql.MigrationsAssembly(migrationsAssembly)); } else if (Convert.ToBoolean(Configuration["BlazorBoilerplate:UsePostgresServer"] ?? "false")) { builder.UseNpgsql(Configuration.GetConnectionString("PostgresConnection"), sql => sql.MigrationsAssembly(migrationsAssembly)); } else { builder.UseSqlite(dbConnString, sql => sql.MigrationsAssembly(migrationsAssembly)); } } services.AddDbContext <ApplicationDbContext>(DbContextOptionsBuilder); services.AddIdentity <ApplicationUser, IdentityRole <Guid> >() .AddRoles <IdentityRole <Guid> >() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddScoped <IUserClaimsPrincipalFactory <ApplicationUser>, AdditionalUserClaimsPrincipalFactory>(); // Adds IdentityServer var identityServerBuilder = services.AddIdentityServer(options => { options.IssuerUri = authAuthority; options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; }) .AddConfigurationStore(options => { options.ConfigureDbContext = DbContextOptionsBuilder; }) .AddOperationalStore(options => { options.ConfigureDbContext = DbContextOptionsBuilder; // this enables automatic token cleanup. this is optional. options.EnableTokenCleanup = true; options.TokenCleanupInterval = 3600; //In Seconds 1 hour }) .AddAspNetIdentity <ApplicationUser>(); X509Certificate2 cert = null; if (_environment.IsDevelopment()) { // The AddDeveloperSigningCredential extension creates temporary key material for signing tokens. // This might be useful to get started, but needs to be replaced by some persistent key material for production scenarios. // See http://docs.identityserver.io/en/release/topics/crypto.html#refcrypto for more information. // https://stackoverflow.com/questions/42351274/identityserver4-hosting-in-iis //.AddDeveloperSigningCredential(true, @"C:\tempkey.rsa") identityServerBuilder.AddDeveloperSigningCredential(); } else { // running on azure // please make sure to replace your vault URI and your certificate name in appsettings.json! if (Convert.ToBoolean(Configuration["HostingOnAzure:RunsOnAzure"]) == true) { // if we use a key vault if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UsingKeyVault"]) == true) { // if managed app identity is used if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UseManagedAppIdentity"]) == true) { try { AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); var certificateBundle = keyVaultClient.GetSecretAsync(Configuration["HostingOnAzure:AzureKeyVault:VaultURI"], Configuration["HostingOnAzure:AzurekeyVault:CertificateName"]).GetAwaiter().GetResult(); var certificate = System.Convert.FromBase64String(certificateBundle.Value); cert = new X509Certificate2(certificate, (string)null, X509KeyStorageFlags.MachineKeySet); } catch (Exception ex) { throw (ex); } } // if app id and app secret are used if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UsingKeyVault"]) == false) { throw new NotImplementedException(); } } } // using local cert store if (Convert.ToBoolean(Configuration["BlazorBoilerplate:UseLocalCertStore"]) == true) { var certificateThumbprint = Configuration["BlazorBoilerplate:CertificateThumbprint"]; using (X509Store store = new X509Store("WebHosting", StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); if (certs.Count > 0) { cert = certs[0]; } else { // import PFX cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "AuthSample.pfx"), "Admin123", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); // save certificate and private key X509Store storeMy = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); storeMy.Open(OpenFlags.ReadWrite); storeMy.Add(cert); } store.Close(); } } // pass the resulting certificate to Identity Server if (cert != null) { identityServerBuilder.AddSigningCredential(cert); } else { throw new FileNotFoundException("No certificate for Identity Server could be retrieved."); } } var authBuilder = services.AddAuthentication(options => { options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(options => { options.Authority = authAuthority; options.SupportedTokens = SupportedTokens.Jwt; options.RequireHttpsMetadata = _environment.IsProduction() ? true : false; options.ApiName = IdentityServerConfig.ApiName; }); //https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins?view=aspnetcore-3.1 if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Google:Enabled"] ?? "false")) { authBuilder.AddGoogle(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Google:ClientId"]; options.ClientSecret = Configuration["ExternalAuthProviders:Google:ClientSecret"]; }); } services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); //Add Policies / Claims / Authorization - https://stormpath.com/blog/tutorial-policy-based-authorization-asp-net-core services.AddAuthorization(options => { options.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy()); options.AddPolicy(Policies.IsUser, Policies.IsUserPolicy()); options.AddPolicy(Policies.IsReadOnly, Policies.IsReadOnlyPolicy()); options.AddPolicy(Policies.IsMyDomain, Policies.IsMyDomainPolicy()); // valid only on serverside operations }); services.AddTransient <IAuthorizationHandler, DomainRequirementHandler>(); services.Configure <IdentityOptions>(options => { // Password settings options.Password.RequireDigit = false; options.Password.RequiredLength = 6; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequireLowercase = false; //options.Password.RequiredUniqueChars = 6; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; options.Lockout.AllowedForNewUsers = true; // Require Confirmed Email User settings if (Convert.ToBoolean(Configuration["BlazorBoilerplate:RequireConfirmedEmail"] ?? "false")) { options.User.RequireUniqueEmail = false; options.SignIn.RequireConfirmedEmail = true; } }); services.Configure <CookiePolicyOptions>(options => { options.MinimumSameSitePolicy = SameSiteMode.None; }); services.ConfigureExternalCookie(options => { // macOS login fix options.Cookie.SameSite = SameSiteMode.None; }); services.ConfigureApplicationCookie(options => { // macOS login fix options.Cookie.SameSite = SameSiteMode.None; options.Cookie.HttpOnly = false; // Suppress redirect on API URLs in ASP.NET Core -> https://stackoverflow.com/a/56384729/54159 options.Events = new CookieAuthenticationEvents() { OnRedirectToAccessDenied = context => { if (context.Request.Path.StartsWithSegments("/api")) { context.Response.StatusCode = (int)(HttpStatusCode.Unauthorized); } return(Task.CompletedTask); }, OnRedirectToLogin = context => { context.Response.StatusCode = 401; return(Task.CompletedTask); } }; }); services.AddControllers().AddNewtonsoftJson(); services.AddSignalR(); services.AddSwaggerDocument(config => { config.PostProcess = document => { document.Info.Version = "0.7.0"; document.Info.Title = "Blazor Boilerplate"; #if ServerSideBlazor #endif document.Info.Description = "Blazor Boilerplate / Starter Template using the Server Side Version"; #if ClientSideBlazor //document.Info.Description = "Blazor Boilerplate / Starter Template using the Client Side / Webassembly Version."; #endif }; }); services.AddResponseCompression(opts => { opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "application/octet-stream" }); }); services.AddScoped <IUserSession, UserSession>(); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton <IEmailConfiguration>(Configuration.GetSection("EmailConfiguration").Get <EmailConfiguration>()); services.AddTransient <IAccountService, AccountService>(); services.AddTransient <IEmailService, EmailService>(); services.AddTransient <IUserProfileService, UserProfileService>(); services.AddTransient <IApiLogService, ApiLogService>(); services.AddTransient <ITodoService, ToDoService>(); services.AddTransient <IMessageService, MessageService>(); services.AddTransient <ICategoryService, CategoryService>(); services.AddTransient <IOrderProductService, OrderProductService>(); // DB Creation and Seeding services.AddTransient <IDatabaseInitializer, DatabaseInitializer>(); //Automapper to map DTO to Models https://www.c-sharpcorner.com/UploadFile/1492b1/crud-operations-using-automapper-in-mvc-application/ var automapperConfig = new MapperConfiguration(configuration => { configuration.AddProfile(new MappingProfile()); }); var autoMapper = automapperConfig.CreateMapper(); services.AddSingleton(autoMapper); //#if ServerSideBlazor services.AddScoped <IAuthorizeApi, AuthorizeApi>(); services.AddScoped <IUserProfileApi, UserProfileApi>(); services.AddScoped <AppState>(); services.AddMatToaster(config => { config.Position = MatToastPosition.BottomRight; config.PreventDuplicates = true; config.NewestOnTop = true; config.ShowCloseButton = true; config.MaximumOpacity = 95; config.VisibleStateDuration = 3000; }); // Setup HttpClient for server side services.AddScoped <HttpClient>(); services.AddRazorPages(); services.AddServerSideBlazor(); // Authentication providers Log.Logger.Debug("Removing AuthenticationStateProvider..."); var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(AuthenticationStateProvider)); if (serviceDescriptor != null) { services.Remove(serviceDescriptor); } Log.Logger.Debug("Adding AuthenticationStateProvider..."); services.AddScoped <AuthenticationStateProvider, IdentityAuthenticationStateProvider>(); //#endif Log.Logger.Debug($"Total Services Registered: {services.Count}"); foreach (var service in services) { Log.Logger.Debug($"\n Service: {service.ServiceType.FullName}\n Lifetime: {service.Lifetime}\n Instance: {service.ImplementationType?.FullName}"); } }
public async Task <string> SetSecretAsync(string secretName, string secretValue) { var bundle = await KeyVaultClient.SetSecretAsync(VaultAddress, secretName, secretValue, null, "plaintext"); return(bundle.Id); }
public ActionResult Index() { string keyVaultName = "<YOUR_VAULT's_NAME>"; string vaultBaseURL = $"https://{keyVaultName}.vault.azure.net"; //Get a token for accessing the Key Vault. var azureServiceTokenProvider = new AzureServiceTokenProvider(); //Create a Key Vault client for accessing the items in the vault; var keyVault = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); // Manage secrets in the Key Vault. // Create a new secret string secretName = "secret-az204"; Task.Run(async() => await keyVault.SetSecretAsync(vaultBaseURL, secretName, "This is a secret testing value")).Wait(); var secret = Task.Run(async() => await keyVault.GetSecretAsync ($"{vaultBaseURL}/secrets/{secretName}")).GetAwaiter().GetResult(); // Update an existing secret Task.Run(async() => await keyVault.SetSecretAsync(vaultBaseURL, secretName, "Updated the secret testing value")).Wait(); secret = Task.Run(async() => await keyVault.GetSecretAsync ($"{vaultBaseURL}/secrets/{secretName}")).GetAwaiter().GetResult(); // Delete the secret Task.Run(async() => await keyVault.DeleteSecretAsync(vaultBaseURL, secretName)).Wait(); // Manage certificates in the Key Vault string certName = "cert-az204"; // Create a new self-signed certificate var policy = new CertificatePolicy { IssuerParameters = new IssuerParameters { Name = "Self", }, KeyProperties = new KeyProperties { Exportable = true, KeySize = 2048, KeyType = "RSA" }, SecretProperties = new SecretProperties { ContentType = "application/x-pkcs12" }, X509CertificateProperties = new X509CertificateProperties { Subject = "CN=AZ204KEYVAULTDEMO" } }; Task.Run(async() => await keyVault.CreateCertificateAsync(vaultBaseURL, certName, policy, new CertificateAttributes { Enabled = true })).Wait(); // When you create a new certificate in the Key Vault it takes some time // before it's ready. // We added some wait time here for the sake of simplicity. Thread.Sleep(10000); var certificate = Task.Run(async() => await keyVault.GetCertificateAsync (vaultBaseURL, certName)).GetAwaiter().GetResult(); // Update properties associated with the certificate. CertificatePolicy updatePolicy = new CertificatePolicy { X509CertificateProperties = new X509CertificateProperties { SubjectAlternativeNames = new SubjectAlternativeNames { DnsNames = new[] { "az204.examref.testing" } } } }; Task.Run(async() => await keyVault.UpdateCertificatePolicyAsync( vaultBaseURL, certName, updatePolicy)).Wait(); Task.Run(async() => await keyVault.CreateCertificateAsync(vaultBaseURL, certName)).Wait(); Thread.Sleep(10000); certificate = Task.Run(async() => await keyVault.GetCertificateAsync( vaultBaseURL, certName)). GetAwaiter().GetResult(); Task.Run(async() => await keyVault.UpdateCertificateAsync(certificate. CertificateIdentifier.Identifier, null, new CertificateAttributes { Enabled = false })).Wait(); Thread.Sleep(10000); // Delete the self-signed certificate. Task.Run(async() => await keyVault.DeleteCertificateAsync(vaultBaseURL, certName)).Wait(); // Manage keys in the Key Vault string keyName = "key-az204"; NewKeyParameters keyParameters = new NewKeyParameters { Kty = "EC", CurveName = "SECP256K1", KeyOps = new[] { "sign", "verify" } }; Task.Run(async() => await keyVault.CreateKeyAsync(vaultBaseURL, keyName, keyParameters)).Wait(); var key = Task.Run(async() => await keyVault.GetKeyAsync(vaultBaseURL, keyName)).GetAwaiter().GetResult(); // Update keys in the Key Vault Task.Run(async() => await keyVault.UpdateKeyAsync(vaultBaseURL, keyName, null, new KeyAttributes { Expires = DateTime.UtcNow. AddYears(1) })).Wait(); key = Task.Run(async() => await keyVault.GetKeyAsync(vaultBaseURL, keyName)).GetAwaiter().GetResult(); // Delete keys from the Key Vault Task.Run(async() => await keyVault.DeleteKeyAsync(vaultBaseURL, keyName)). Wait(); return(View()); }
public async Task <byte[]> DecryptAsync(string keyId, byte[] dataToDecrypt) { var operationResult = await KeyVaultClient.DecryptAsync(keyId, JsonWebKeyEncryptionAlgorithm.RSAOAEP, dataToDecrypt); return(operationResult.Result); }
private async Task CertificatesMigrationGuide() { #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_Create AzureServiceTokenProvider provider = new AzureServiceTokenProvider(); KeyVaultClient client = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback)); #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_Create #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateWithOptions using (HttpClient httpClient = new HttpClient()) { //@@AzureServiceTokenProvider provider = new AzureServiceTokenProvider(); /*@@*/ provider = new AzureServiceTokenProvider(); //@@KeyVaultClient client = new KeyVaultClient( /*@@*/ client = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback), httpClient); } #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateWithOptions #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateCustomPolicy CertificatePolicy policy = new CertificatePolicy { IssuerParameters = new IssuerParameters("issuer-name"), SecretProperties = new SecretProperties("application/x-pkcs12"), KeyProperties = new KeyProperties { KeyType = "RSA", KeySize = 2048, ReuseKey = true }, X509CertificateProperties = new X509CertificateProperties("CN=customdomain.com") { KeyUsage = new[] { KeyUsageType.CRLSign, KeyUsageType.DataEncipherment, KeyUsageType.DigitalSignature, KeyUsageType.KeyEncipherment, KeyUsageType.KeyAgreement, KeyUsageType.KeyCertSign }, ValidityInMonths = 12 }, LifetimeActions = new[] { new LifetimeAction( new Trigger { DaysBeforeExpiry = 90 }, new Models.Action(ActionType.AutoRenew)) } }; #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateCustomPolicy { #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateCertificate CertificateBundle certificate = null; // Start certificate creation. // Depending on the policy and your business process, this could even take days for manual signing. CertificateOperation createOperation = await client.CreateCertificateAsync("https://myvault.vault.azure.net", "certificate-name", policy); while (true) { if ("InProgress".Equals(createOperation.Status, StringComparison.OrdinalIgnoreCase)) { await Task.Delay(TimeSpan.FromSeconds(20)); createOperation = await client.GetCertificateOperationAsync("https://myvault.vault.azure.net", "certificate-name"); continue; } if ("Completed".Equals(createOperation.Status, StringComparison.OrdinalIgnoreCase)) { certificate = await client.GetCertificateAsync(createOperation.Id); break; } throw new Exception(string.Format( CultureInfo.InvariantCulture, "Polling on pending certificate returned an unexpected result. Error code = {0}, Error message = {1}", createOperation.Error.Code, createOperation.Error.Message)); } // If you need to restart the application you can recreate the operation and continue awaiting. do { createOperation = await client.GetCertificateOperationAsync("https://myvault.vault.azure.net", "certificate-name"); if ("InProgress".Equals(createOperation.Status, StringComparison.OrdinalIgnoreCase)) { await Task.Delay(TimeSpan.FromSeconds(20)); continue; } if ("Completed".Equals(createOperation.Status, StringComparison.OrdinalIgnoreCase)) { certificate = await client.GetCertificateAsync(createOperation.Id); break; } throw new Exception(string.Format( CultureInfo.InvariantCulture, "Polling on pending certificate returned an unexpected result. Error code = {0}, Error message = {1}", createOperation.Error.Code, createOperation.Error.Message)); } while (true); #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateCertificate } { #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_ImportCertificate byte[] cer = File.ReadAllBytes("certificate.pfx"); string cerBase64 = Convert.ToBase64String(cer); CertificateBundle certificate = await client.ImportCertificateAsync( "https://myvault.vault.azure.net", "certificate-name", cerBase64, certificatePolicy : policy); #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_ImportCertificate } #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateSelfSignedPolicy //@@CertificatePolicy policy = new CertificatePolicy /*@@*/ policy = new CertificatePolicy { IssuerParameters = new IssuerParameters("Self"), X509CertificateProperties = new X509CertificateProperties("CN=DefaultPolicy") }; #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_CreateSelfSignedPolicy // TODO { #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_ListCertificates IPage <CertificateItem> page = await client.GetCertificatesAsync("https://myvault.vault.azure.net"); foreach (CertificateItem item in page) { CertificateIdentifier certificateId = item.Identifier; CertificateBundle certificate = await client.GetCertificateAsync(certificateId.Vault, certificateId.Name); } while (page.NextPageLink != null) { page = await client.GetCertificatesNextAsync(page.NextPageLink); foreach (CertificateItem item in page) { CertificateIdentifier certificateId = item.Identifier; CertificateBundle certificate = await client.GetCertificateAsync(certificateId.Vault, certificateId.Name); } } #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_ListCertificates } { #region Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_DeleteCertificate // Delete the certificate. DeletedCertificateBundle deletedCertificate = await client.DeleteCertificateAsync("https://myvault.vault.azure.net", "certificate-name"); // Purge or recover the deleted certificate if soft delete is enabled. if (deletedCertificate.RecoveryId != null) { DeletedCertificateIdentifier deletedCertificateId = deletedCertificate.RecoveryIdentifier; // Deleting a certificate does not happen immediately. Wait a while and check if the deleted certificate exists. while (true) { try { await client.GetDeletedCertificateAsync(deletedCertificateId.Vault, deletedCertificateId.Name); // Finally deleted. break; } catch (KeyVaultErrorException ex) when(ex.Response.StatusCode == HttpStatusCode.NotFound) { // Not yet deleted... } } // Purge the deleted certificate. await client.PurgeDeletedCertificateAsync(deletedCertificateId.Vault, deletedCertificateId.Name); // You can also recover the deleted certificate using RecoverDeletedCertificateAsync. } #endregion Snippet:Microsoft_Azure_KeyVault_Certificates_Snippets_MigrationGuide_DeleteCertificate } }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup <Startup>()) .ConfigureAppConfiguration( (ctx, builder) => { //Build the config from sources we have var config = builder.Build(); var uriList = new List <string>(); // Get the uri for the Vault from configuration // Try to get a string from configutation // This will happen when the config looks like: // { // "KeyVault":{ // "Uri": "sample.vault.azure.net/" // } // } var uriString = config["KeyVault:Uri"]; if (!string.IsNullOrWhiteSpace(uriString)) { uriList.Add(uriString); } // This will happen when the config looks like: // { // "KeyVault":{ // "Uri": [ // "sample1.vault.azure.net/", // "sample2.vault.azure.net/" // ] // } // } else { uriList = config.GetSection("KeyVault:Uri").Get <List <string> >(); } // Add KeyVault only if the uri is not empty if (uriList?.Count > 0) { // Create Managed Service Identity token provider var azureServiceTokenProvider = new AzureServiceTokenProvider(); // Create the Key Vault client var keyVaultClient = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback( azureServiceTokenProvider.KeyVaultTokenCallback) ); foreach (var uri in uriList) { // Add Key Vault to configuration pipeline _ = builder.AddAzureKeyVault( uri, keyVaultClient, new PrefixKeyVaultSecretManager() ); } } } );
static void Main(string[] args) { KeyBundle keyBundle = null; // The key specification and attributes Secret secret = null; string keyName = string.Empty; string secretName = string.Empty; inputValidator = new InputValidator(args); TracingAdapter.AddTracingInterceptor(new ConsoleTracingInterceptor()); TracingAdapter.IsEnabled = inputValidator.GetTracingEnabled(); var clientId = ConfigurationManager.AppSettings["AuthClientId"]; var cerificateThumbprint = ConfigurationManager.AppSettings["AuthCertThumbprint"]; var certificate = FindCertificateByThumbprint(cerificateThumbprint); var assertionCert = new ClientAssertionCertificate(clientId, certificate); keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback( (authority, resource, scope) => GetAccessToken(authority, resource, scope, assertionCert)), GetHttpClient()); // SECURITY: DO NOT USE IN PRODUCTION CODE; FOR TEST PURPOSES ONLY //ServicePointManager.ServerCertificateValidationCallback += ( sender, cert, chain, sslPolicyErrors ) => true; List<KeyOperationType> successfulOperations = new List<KeyOperationType>(); List<KeyOperationType> failedOperations = new List<KeyOperationType>(); foreach (var operation in inputValidator.GetKeyOperations()) { try { Console.Out.WriteLine(string.Format("\n\n {0} is in process ...", operation.ToString())); switch (operation) { case KeyOperationType.CREATE_KEY: keyBundle = CreateKey(keyBundle, out keyName); break; case KeyOperationType.IMPORT_KEY: keyBundle = ImportKey(out keyName); break; case KeyOperationType.GET_KEY: keyBundle = GetKey(keyBundle); break; case KeyOperationType.LIST_KEYVERSIONS: ListKeyVersions(keyName); break; case KeyOperationType.UPDATE_KEY: keyBundle = UpdateKey(keyName); break; case KeyOperationType.DELETE_KEY: DeleteKey(keyName); break; case KeyOperationType.BACKUP_RESTORE: keyBundle = BackupRestoreKey(keyName); break; case KeyOperationType.SIGN_VERIFY: SignVerify(keyBundle); break; case KeyOperationType.ENCRYPT_DECRYPT: EncryptDecrypt(keyBundle); break; case KeyOperationType.ENCRYPT: Encrypt(keyBundle); break; case KeyOperationType.DECRYPT: Decrypt(keyBundle); break; case KeyOperationType.WRAP_UNWRAP: WrapUnwrap(keyBundle); break; case KeyOperationType.CREATE_SECRET: secret = CreateSecret(out secretName); break; case KeyOperationType.GET_SECRET: secret = GetSecret(secret.Id); break; case KeyOperationType.LIST_SECRETS: ListSecrets(); break; case KeyOperationType.DELETE_SECRET: secret = DeleteSecret(secretName); break; } successfulOperations.Add(operation); } catch (KeyVaultClientException exception) { // The Key Vault exceptions are logged but not thrown to avoid blocking execution for other commands running in batch Console.Out.WriteLine("Operation failed: {0}", exception.Message); failedOperations.Add(operation); } } Console.Out.WriteLine("\n\n---------------Successful Key Vault operations:---------------"); foreach (KeyOperationType type in successfulOperations) Console.Out.WriteLine("\t{0}", type); if (failedOperations.Count > 0) { Console.Out.WriteLine("\n\n---------------Failed Key Vault operations:---------------"); foreach (KeyOperationType type in failedOperations) Console.Out.WriteLine("\t{0}", type); } Console.Out.WriteLine(); Console.Out.Write("Press enter to continue . . ."); Console.In.Read(); }
private async Task SecretsMigrationGuide() { #region Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_Create AzureServiceTokenProvider provider = new AzureServiceTokenProvider(); KeyVaultClient client = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback)); #endregion Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_Create #region Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_CreateWithOptions using (HttpClient httpClient = new HttpClient()) { //@@AzureServiceTokenProvider provider = new AzureServiceTokenProvider(); /*@@*/ provider = new AzureServiceTokenProvider(); //@@KeyVaultClient client = new KeyVaultClient( /*@@*/ client = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback), httpClient); } #endregion Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_CreateWithOptions { #region Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_SetSecret SecretBundle secret = await client.SetSecretAsync("https://myvault.vault.azure.net", "secret-name", "secret-value"); #endregion Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_SetSecret } { #region Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_GetSecret // Get the latest secret value. SecretBundle secret = await client.GetSecretAsync("https://myvault.vault.azure.net", "secret-name", null); // Get a specific secret value. SecretBundle secretVersion = await client.GetSecretAsync("https://myvault.vault.azure.net", "secret-name", "e43af03a7cbc47d4a4e9f11540186048"); #endregion Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_GetSecret } { #region Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_ListSecrets IPage <SecretItem> page = await client.GetSecretsAsync("https://myvault.vault.azure.net"); foreach (SecretItem item in page) { SecretIdentifier secretId = item.Identifier; SecretBundle secret = await client.GetSecretAsync(secretId.Vault, secretId.Name); } while (page.NextPageLink != null) { page = await client.GetSecretsNextAsync(page.NextPageLink); foreach (SecretItem item in page) { SecretIdentifier secretId = item.Identifier; SecretBundle secret = await client.GetSecretAsync(secretId.Vault, secretId.Name); } } #endregion Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_ListSecrets } { #region Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_DeleteSecret // Delete the secret. DeletedSecretBundle deletedSecret = await client.DeleteSecretAsync("https://myvault.vault.azure.net", "secret-name"); // Purge or recover the deleted secret if soft delete is enabled. if (deletedSecret.RecoveryId != null) { DeletedSecretIdentifier deletedSecretId = deletedSecret.RecoveryIdentifier; // Deleting a secret does not happen immediately. Wait a while and check if the deleted secret exists. while (true) { try { await client.GetDeletedSecretAsync(deletedSecretId.Vault, deletedSecretId.Name); // Finally deleted. break; } catch (KeyVaultErrorException ex) when(ex.Response.StatusCode == HttpStatusCode.NotFound) { // Not yet deleted... } } // Purge the deleted secret. await client.PurgeDeletedSecretAsync(deletedSecretId.Vault, deletedSecretId.Name); // You can also recover the deleted secret using RecoverDeletedSecretAsync. } #endregion Snippet:Microsoft_Azure_KeyVault_Secrets_Snippets_MigrationGuide_DeleteSecret } }