diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index c2bdbb01d..2d5817788 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -22,6 +22,8 @@ + + @@ -29,12 +31,10 @@ - - diff --git a/src/Core/Services/Implementations/AzureAttachmentStorageService.cs b/src/Core/Services/Implementations/AzureAttachmentStorageService.cs index c9e836091..82b4e5729 100644 --- a/src/Core/Services/Implementations/AzureAttachmentStorageService.cs +++ b/src/Core/Services/Implementations/AzureAttachmentStorageService.cs @@ -2,12 +2,13 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using Azure.Storage.Blobs; +using Azure.Storage.Blobs.Models; +using Azure.Storage.Sas; using Bit.Core.Enums; using Bit.Core.Models.Data; using Bit.Core.Models.Table; using Bit.Core.Settings; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Blob; namespace Bit.Core.Services { @@ -18,8 +19,8 @@ namespace Bit.Core.Services private const string _defaultContainerName = "attachments"; private readonly static string[] _attachmentContainerName = { "attachments", "attachments-v2" }; private static readonly TimeSpan blobLinkLiveTime = TimeSpan.FromMinutes(1); - private readonly CloudBlobClient _blobClient; - private readonly Dictionary _attachmentContainers = new Dictionary(); + private readonly BlobServiceClient _blobServiceClient; + private readonly Dictionary _attachmentContainers = new Dictionary(); private string BlobName(Guid cipherId, CipherAttachment.MetaData attachmentData, Guid? organizationId = null, bool temp = false) => string.Concat( temp ? "temp/" : "", @@ -54,121 +55,122 @@ namespace Bit.Core.Services public AzureAttachmentStorageService( GlobalSettings globalSettings) { - var storageAccount = CloudStorageAccount.Parse(globalSettings.Attachment.ConnectionString); - _blobClient = storageAccount.CreateCloudBlobClient(); + _blobServiceClient = new BlobServiceClient(globalSettings.Attachment.ConnectionString); } public async Task GetAttachmentDownloadUrlAsync(Cipher cipher, CipherAttachment.MetaData attachmentData) { await InitAsync(attachmentData.ContainerName); - var blob = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData)); - var accessPolicy = new SharedAccessBlobPolicy() - { - SharedAccessExpiryTime = DateTime.UtcNow.Add(blobLinkLiveTime), - Permissions = SharedAccessBlobPermissions.Read - }; - - return blob.Uri + blob.GetSharedAccessSignature(accessPolicy); + var blobClient = _attachmentContainers[attachmentData.ContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData)); + var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTime.UtcNow.Add(blobLinkLiveTime)); + return sasUri.ToString(); } public async Task GetAttachmentUploadUrlAsync(Cipher cipher, CipherAttachment.MetaData attachmentData) { await InitAsync(EventGridEnabledContainerName); - var blob = _attachmentContainers[EventGridEnabledContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData)); + var blobClient = _attachmentContainers[EventGridEnabledContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData)); attachmentData.ContainerName = EventGridEnabledContainerName; - var accessPolicy = new SharedAccessBlobPolicy() - { - SharedAccessExpiryTime = DateTime.UtcNow.Add(blobLinkLiveTime), - Permissions = SharedAccessBlobPermissions.Create | SharedAccessBlobPermissions.Write, - }; - - return blob.Uri + blob.GetSharedAccessSignature(accessPolicy); + var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Create | BlobSasPermissions.Write, DateTime.UtcNow.Add(blobLinkLiveTime)); + return sasUri.ToString(); } public async Task UploadNewAttachmentAsync(Stream stream, Cipher cipher, CipherAttachment.MetaData attachmentData) { attachmentData.ContainerName = _defaultContainerName; await InitAsync(_defaultContainerName); - var blob = _attachmentContainers[_defaultContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData)); - blob.Metadata.Add("cipherId", cipher.Id.ToString()); + var blobClient = _attachmentContainers[_defaultContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData)); + + var metadata = new Dictionary(); + metadata.Add("cipherId", cipher.Id.ToString()); if (cipher.UserId.HasValue) { - blob.Metadata.Add("userId", cipher.UserId.Value.ToString()); + metadata.Add("userId", cipher.UserId.Value.ToString()); } else { - blob.Metadata.Add("organizationId", cipher.OrganizationId.Value.ToString()); + metadata.Add("organizationId", cipher.OrganizationId.Value.ToString()); } - blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\""; - await blob.UploadFromStreamAsync(stream); + + var headers = new BlobHttpHeaders + { + ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\"" + }; + await blobClient.UploadAsync(stream, new BlobUploadOptions { Metadata = metadata, HttpHeaders = headers }); } public async Task UploadShareAttachmentAsync(Stream stream, Guid cipherId, Guid organizationId, CipherAttachment.MetaData attachmentData) { attachmentData.ContainerName = _defaultContainerName; await InitAsync(_defaultContainerName); - var blob = _attachmentContainers[_defaultContainerName].GetBlockBlobReference( + var blobClient = _attachmentContainers[_defaultContainerName].GetBlobClient( BlobName(cipherId, attachmentData, organizationId, temp: true)); - blob.Metadata.Add("cipherId", cipherId.ToString()); - blob.Metadata.Add("organizationId", organizationId.ToString()); - blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\""; - await blob.UploadFromStreamAsync(stream); + + var metadata = new Dictionary(); + metadata.Add("cipherId", cipherId.ToString()); + metadata.Add("organizationId", organizationId.ToString()); + + var headers = new BlobHttpHeaders + { + ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\"" + }; + await blobClient.UploadAsync(stream, new BlobUploadOptions { Metadata = metadata, HttpHeaders = headers }); } public async Task StartShareAttachmentAsync(Guid cipherId, Guid organizationId, CipherAttachment.MetaData data) { await InitAsync(data.ContainerName); - var source = _attachmentContainers[data.ContainerName].GetBlockBlobReference( + var source = _attachmentContainers[data.ContainerName].GetBlobClient( BlobName(cipherId, data, organizationId, temp: true)); - if (!(await source.ExistsAsync())) + if (!await source.ExistsAsync()) { return; } await InitAsync(_defaultContainerName); - var dest = _attachmentContainers[_defaultContainerName].GetBlockBlobReference(BlobName(cipherId, data)); - if (!(await dest.ExistsAsync())) + var dest = _attachmentContainers[_defaultContainerName].GetBlobClient(BlobName(cipherId, data)); + if (!await dest.ExistsAsync()) { return; } - var original = _attachmentContainers[_defaultContainerName].GetBlockBlobReference( + var original = _attachmentContainers[_defaultContainerName].GetBlobClient( BlobName(cipherId, data, temp: true)); await original.DeleteIfExistsAsync(); - await original.StartCopyAsync(dest); + await original.StartCopyFromUriAsync(dest.Uri); await dest.DeleteIfExistsAsync(); - await dest.StartCopyAsync(source); + await dest.StartCopyFromUriAsync(source.Uri); } public async Task RollbackShareAttachmentAsync(Guid cipherId, Guid organizationId, CipherAttachment.MetaData attachmentData, string originalContainer) { await InitAsync(attachmentData.ContainerName); - var source = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference( + var source = _attachmentContainers[attachmentData.ContainerName].GetBlobClient( BlobName(cipherId, attachmentData, organizationId, temp: true)); await source.DeleteIfExistsAsync(); await InitAsync(originalContainer); - var original = _attachmentContainers[originalContainer].GetBlockBlobReference( + var original = _attachmentContainers[originalContainer].GetBlobClient( BlobName(cipherId, attachmentData, temp: true)); - if (!(await original.ExistsAsync())) + if (!await original.ExistsAsync()) { return; } - var dest = _attachmentContainers[originalContainer].GetBlockBlobReference( + var dest = _attachmentContainers[originalContainer].GetBlobClient( BlobName(cipherId, attachmentData)); await dest.DeleteIfExistsAsync(); - await dest.StartCopyAsync(original); + await dest.StartCopyFromUriAsync(original.Uri); await original.DeleteIfExistsAsync(); } public async Task DeleteAttachmentAsync(Guid cipherId, CipherAttachment.MetaData attachmentData) { await InitAsync(attachmentData.ContainerName); - var blob = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference( + var blobClient = _attachmentContainers[attachmentData.ContainerName].GetBlobClient( BlobName(cipherId, attachmentData)); - await blob.DeleteIfExistsAsync(); + await blobClient.DeleteIfExistsAsync(); } public async Task CleanupAsync(Guid cipherId) => await DeleteAttachmentsForPathAsync($"temp/{cipherId}"); @@ -190,35 +192,42 @@ namespace Bit.Core.Services { await InitAsync(attachmentData.ContainerName); - var blob = _attachmentContainers[attachmentData.ContainerName].GetBlockBlobReference(BlobName(cipher.Id, attachmentData)); + var blobClient = _attachmentContainers[attachmentData.ContainerName].GetBlobClient(BlobName(cipher.Id, attachmentData)); - if (!blob.Exists()) + try + { + var blobProperties = await blobClient.GetPropertiesAsync(); + + var metadata = blobProperties.Value.Metadata; + metadata["cipherId"] = cipher.Id.ToString(); + if (cipher.UserId.HasValue) + { + metadata["userId"] = cipher.UserId.Value.ToString(); + } + else + { + metadata["organizationId"] = cipher.OrganizationId.Value.ToString(); + } + await blobClient.SetMetadataAsync(metadata); + + var headers = new BlobHttpHeaders + { + ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\"" + }; + await blobClient.SetHttpHeadersAsync(headers); + + var length = blobProperties.Value.ContentLength; + if (length < attachmentData.Size - leeway || length > attachmentData.Size + leeway) + { + return (false, length); + } + + return (true, length); + } + catch (Exception ex) { return (false, null); } - - blob.FetchAttributes(); - - blob.Metadata["cipherId"] = cipher.Id.ToString(); - if (cipher.UserId.HasValue) - { - blob.Metadata["userId"] = cipher.UserId.Value.ToString(); - } - else - { - blob.Metadata["organizationId"] = cipher.OrganizationId.Value.ToString(); - } - blob.Properties.ContentDisposition = $"attachment; filename=\"{attachmentData.AttachmentId}\""; - blob.SetMetadata(); - blob.SetProperties(); - - var length = blob.Properties.Length; - if (length < attachmentData.Size - leeway || length > attachmentData.Size + leeway) - { - return (false, length); - } - - return (true, length); } private async Task DeleteAttachmentsForPathAsync(string path) @@ -226,24 +235,13 @@ namespace Bit.Core.Services foreach (var container in _attachmentContainerName) { await InitAsync(container); - var segment = await _attachmentContainers[container].ListBlobsSegmentedAsync(path, true, BlobListingDetails.None, 100, null, null, null); + var blobContainerClient = _attachmentContainers[container]; - while (true) + var blobItems = blobContainerClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: path); + await foreach (var blobItem in blobItems) { - foreach (var blob in segment.Results) - { - if (blob is CloudBlockBlob blockBlob) - { - await blockBlob.DeleteIfExistsAsync(); - } - } - - if (segment.ContinuationToken == null) - { - break; - } - - segment = await _attachmentContainers[container].ListBlobsSegmentedAsync(segment.ContinuationToken); + BlobClient blobClient = blobContainerClient.GetBlobClient(blobItem.Name); + await blobClient.DeleteIfExistsAsync(); } } } @@ -252,14 +250,14 @@ namespace Bit.Core.Services { if (!_attachmentContainers.ContainsKey(containerName) || _attachmentContainers[containerName] == null) { - _attachmentContainers[containerName] = _blobClient.GetContainerReference(containerName); + _attachmentContainers[containerName] = _blobServiceClient.GetBlobContainerClient(containerName); if (containerName == "attachments") { - await _attachmentContainers[containerName].CreateIfNotExistsAsync(BlobContainerPublicAccessType.Blob, null, null); + await _attachmentContainers[containerName].CreateIfNotExistsAsync(PublicAccessType.Blob, null, null); } else { - await _attachmentContainers[containerName].CreateIfNotExistsAsync(BlobContainerPublicAccessType.Off, null, null); + await _attachmentContainers[containerName].CreateIfNotExistsAsync(PublicAccessType.None, null, null); } } } diff --git a/src/Core/Services/Implementations/AzureSendFileStorageService.cs b/src/Core/Services/Implementations/AzureSendFileStorageService.cs index 9e536503b..dab251070 100644 --- a/src/Core/Services/Implementations/AzureSendFileStorageService.cs +++ b/src/Core/Services/Implementations/AzureSendFileStorageService.cs @@ -1,11 +1,14 @@ using System; +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using Azure; +using Azure.Storage.Blobs; +using Azure.Storage.Blobs.Models; +using Azure.Storage.Sas; using Bit.Core.Enums; using Bit.Core.Models.Table; using Bit.Core.Settings; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Blob; namespace Bit.Core.Services { @@ -13,8 +16,8 @@ namespace Bit.Core.Services { public const string FilesContainerName = "sendfiles"; private static readonly TimeSpan _downloadLinkLiveTime = TimeSpan.FromMinutes(1); - private readonly CloudBlobClient _blobClient; - private CloudBlobContainer _sendFilesContainer; + private readonly BlobServiceClient _blobServiceClient; + private BlobContainerClient _sendFilesContainerClient; public FileUploadType FileUploadType => FileUploadType.Azure; @@ -24,24 +27,31 @@ namespace Bit.Core.Services public AzureSendFileStorageService( GlobalSettings globalSettings) { - var storageAccount = CloudStorageAccount.Parse(globalSettings.Send.ConnectionString); - _blobClient = storageAccount.CreateCloudBlobClient(); + _blobServiceClient = new BlobServiceClient(globalSettings.Send.ConnectionString); } public async Task UploadNewFileAsync(Stream stream, Send send, string fileId) { await InitAsync(); - var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId)); + + var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId)); + + var metadata = new Dictionary(); if (send.UserId.HasValue) { - blob.Metadata.Add("userId", send.UserId.Value.ToString()); + metadata.Add("userId", send.UserId.Value.ToString()); } else { - blob.Metadata.Add("organizationId", send.OrganizationId.Value.ToString()); + metadata.Add("organizationId", send.OrganizationId.Value.ToString()); } - blob.Properties.ContentDisposition = $"attachment; filename=\"{fileId}\""; - await blob.UploadFromStreamAsync(stream); + + var headers = new BlobHttpHeaders + { + ContentDisposition = $"attachment; filename=\"{fileId}\"" + }; + + await blobClient.UploadAsync(stream, new BlobUploadOptions { Metadata = metadata, HttpHeaders = headers }); } public async Task DeleteFileAsync(Send send, string fileId) => await DeleteBlobAsync(BlobName(send, fileId)); @@ -49,8 +59,8 @@ namespace Bit.Core.Services public async Task DeleteBlobAsync(string blobName) { await InitAsync(); - var blob = _sendFilesContainer.GetBlockBlobReference(blobName); - await blob.DeleteIfExistsAsync(); + var blobClient = _sendFilesContainerClient.GetBlobClient(blobName); + await blobClient.DeleteIfExistsAsync(); } public async Task DeleteFilesForOrganizationAsync(Guid organizationId) @@ -66,70 +76,66 @@ namespace Bit.Core.Services public async Task GetSendFileDownloadUrlAsync(Send send, string fileId) { await InitAsync(); - var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId)); - var accessPolicy = new SharedAccessBlobPolicy() - { - SharedAccessExpiryTime = DateTime.UtcNow.Add(_downloadLinkLiveTime), - Permissions = SharedAccessBlobPermissions.Read, - }; - - return blob.Uri + blob.GetSharedAccessSignature(accessPolicy); + var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId)); + var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTime.UtcNow.Add(_downloadLinkLiveTime)); + return sasUri.ToString(); } public async Task GetSendFileUploadUrlAsync(Send send, string fileId) { await InitAsync(); - var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId)); - - var accessPolicy = new SharedAccessBlobPolicy() - { - SharedAccessExpiryTime = DateTime.UtcNow.Add(_downloadLinkLiveTime), - Permissions = SharedAccessBlobPermissions.Create | SharedAccessBlobPermissions.Write, - }; - - return blob.Uri + blob.GetSharedAccessSignature(accessPolicy); + var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId)); + var sasUri = blobClient.GenerateSasUri(BlobSasPermissions.Create | BlobSasPermissions.Write, DateTime.UtcNow.Add(_downloadLinkLiveTime)); + return sasUri.ToString(); } public async Task<(bool, long?)> ValidateFileAsync(Send send, string fileId, long expectedFileSize, long leeway) { await InitAsync(); - var blob = _sendFilesContainer.GetBlockBlobReference(BlobName(send, fileId)); + var blobClient = _sendFilesContainerClient.GetBlobClient(BlobName(send, fileId)); - if (!blob.Exists()) + try + { + var blobProperties = await blobClient.GetPropertiesAsync(); + var metadata = blobProperties.Value.Metadata; + + if (send.UserId.HasValue) + { + metadata["userId"] = send.UserId.Value.ToString(); + } + else + { + metadata["organizationId"] = send.OrganizationId.Value.ToString(); + } + await blobClient.SetMetadataAsync(metadata); + + var headers = new BlobHttpHeaders + { + ContentDisposition = $"attachment; filename=\"{fileId}\"" + }; + await blobClient.SetHttpHeadersAsync(headers); + + var length = blobProperties.Value.ContentLength; + if (length < expectedFileSize - leeway || length > expectedFileSize + leeway) + { + return (false, length); + } + + return (true, length); + } + catch (Exception ex) { return (false, null); } - - blob.FetchAttributes(); - - if (send.UserId.HasValue) - { - blob.Metadata["userId"] = send.UserId.Value.ToString(); - } - else - { - blob.Metadata["organizationId"] = send.OrganizationId.Value.ToString(); - } - blob.Properties.ContentDisposition = $"attachment; filename=\"{fileId}\""; - blob.SetMetadata(); - blob.SetProperties(); - - var length = blob.Properties.Length; - if (length < expectedFileSize - leeway || length > expectedFileSize + leeway) - { - return (false, length); - } - - return (true, length); } private async Task InitAsync() { - if (_sendFilesContainer == null) + if (_sendFilesContainerClient == null) { - _sendFilesContainer = _blobClient.GetContainerReference(FilesContainerName); - await _sendFilesContainer.CreateIfNotExistsAsync(BlobContainerPublicAccessType.Off, null, null); + _sendFilesContainerClient = _blobServiceClient.GetBlobContainerClient(FilesContainerName); + await _sendFilesContainerClient.CreateIfNotExistsAsync(PublicAccessType.None, null, null); } } } diff --git a/src/Core/Services/Implementations/LicensingService.cs b/src/Core/Services/Implementations/LicensingService.cs index 6254646ee..ad7ec0988 100644 --- a/src/Core/Services/Implementations/LicensingService.cs +++ b/src/Core/Services/Implementations/LicensingService.cs @@ -11,7 +11,6 @@ using Bit.Core.Repositories; using Bit.Core.Settings; using Bit.Core.Utilities; using Microsoft.AspNetCore.Hosting; -using Microsoft.Azure.Storage; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Newtonsoft.Json; @@ -57,8 +56,7 @@ namespace Bit.Core.Services else if (CoreHelpers.SettingHasValue(_globalSettings.Storage?.ConnectionString) && CoreHelpers.SettingHasValue(_globalSettings.LicenseCertificatePassword)) { - var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString); - _certificate = CoreHelpers.GetBlobCertificateAsync(storageAccount, "certificates", + _certificate = CoreHelpers.GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates", "licensing.pfx", _globalSettings.LicenseCertificatePassword) .GetAwaiter().GetResult(); } diff --git a/src/Core/Utilities/CoreHelpers.cs b/src/Core/Utilities/CoreHelpers.cs index 42202227e..92e237d74 100644 --- a/src/Core/Utilities/CoreHelpers.cs +++ b/src/Core/Utilities/CoreHelpers.cs @@ -10,10 +10,11 @@ using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; -using System.Threading; using System.Threading.Tasks; using System.Web; -using Azure.Storage.Queues; +using Azure; +using Azure.Storage.Blobs; +using Azure.Storage.Blobs.Models; using Azure.Storage.Queues.Models; using Bit.Core.Context; using Bit.Core.Enums; @@ -24,8 +25,6 @@ using Bit.Core.Settings; using Dapper; using IdentityModel; using Microsoft.AspNetCore.DataProtection; -using Microsoft.Azure.Storage; -using Microsoft.Azure.Storage.Blob; using MimeKit; using Newtonsoft.Json; @@ -253,22 +252,27 @@ namespace Bit.Core.Utilities } } - public async static Task GetBlobCertificateAsync(CloudStorageAccount cloudStorageAccount, - string container, string file, string password) + public async static Task GetBlobCertificateAsync(string connectionString, string container, string file, string password) { - var blobClient = cloudStorageAccount.CreateCloudBlobClient(); - var containerRef = blobClient.GetContainerReference(container); - if (await containerRef.ExistsAsync().ConfigureAwait(false)) + try { - var blobRef = containerRef.GetBlobReference(file); - if (await blobRef.ExistsAsync().ConfigureAwait(false)) - { - var blobBytes = new byte[blobRef.Properties.Length]; - await blobRef.DownloadToByteArrayAsync(blobBytes, 0).ConfigureAwait(false); - return new X509Certificate2(blobBytes, password); - } + var blobServiceClient = new BlobServiceClient(connectionString); + var containerRef2 = blobServiceClient.GetBlobContainerClient(container); + var blobRef = containerRef2.GetBlobClient(file); + + using var memStream = new MemoryStream(); + await blobRef.DownloadToAsync(memStream).ConfigureAwait(false); + return new X509Certificate2(memStream.ToArray(), password); + } + catch (RequestFailedException ex) + when (ex.ErrorCode == BlobErrorCode.ContainerNotFound || ex.ErrorCode == BlobErrorCode.BlobNotFound) + { + return null; + } + catch (Exception) + { + return null; } - return null; } public static long ToEpocMilliseconds(DateTime date) @@ -756,8 +760,7 @@ namespace Bit.Core.Utilities SettingHasValue(globalSettings.Storage?.ConnectionString) && SettingHasValue(globalSettings.IdentityServer.CertificatePassword)) { - var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString); - return GetBlobCertificateAsync(storageAccount, "certificates", + return GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates", "identity.pfx", globalSettings.IdentityServer.CertificatePassword).GetAwaiter().GetResult(); } return null; diff --git a/src/Core/Utilities/ServiceCollectionExtensions.cs b/src/Core/Utilities/ServiceCollectionExtensions.cs index c9bf1f8a7..8e28f5a6a 100644 --- a/src/Core/Utilities/ServiceCollectionExtensions.cs +++ b/src/Core/Utilities/ServiceCollectionExtensions.cs @@ -28,7 +28,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.Localization; -using Microsoft.Azure.Storage; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -471,7 +470,7 @@ namespace Bit.Core.Utilities public static void AddCustomDataProtectionServices( this IServiceCollection services, IWebHostEnvironment env, GlobalSettings globalSettings) { - var builder = services.AddDataProtection().SetApplicationName("Bitwarden"); + var builder = services.AddDataProtection(options => options.ApplicationDiscriminator = "Bitwarden"); if (env.IsDevelopment()) { return; @@ -484,7 +483,6 @@ namespace Bit.Core.Utilities if (!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Storage?.ConnectionString)) { - var storageAccount = CloudStorageAccount.Parse(globalSettings.Storage.ConnectionString); X509Certificate2 dataProtectionCert = null; if (CoreHelpers.SettingHasValue(globalSettings.DataProtection.CertificateThumbprint)) { @@ -493,12 +491,13 @@ namespace Bit.Core.Utilities } else if (CoreHelpers.SettingHasValue(globalSettings.DataProtection.CertificatePassword)) { - dataProtectionCert = CoreHelpers.GetBlobCertificateAsync(storageAccount, "certificates", + dataProtectionCert = CoreHelpers.GetBlobCertificateAsync(globalSettings.Storage.ConnectionString, "certificates", "dataprotection.pfx", globalSettings.DataProtection.CertificatePassword) .GetAwaiter().GetResult(); } + //TODO djsmith85 Check if this is the correct container name builder - .PersistKeysToAzureBlobStorage(storageAccount, "aspnet-dataprotection/keys.xml") + .PersistKeysToAzureBlobStorage(globalSettings.Storage.ConnectionString, "aspnet-dataprotection", "keys.xml") .ProtectKeysWithCertificate(dataProtectionCert); } }