1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-03 09:02:48 -05:00

Migrate deprecated Microsoft.Azure.Storage.Blob to Azure.Storage.Blobs (#1732)

* Migrate from deprecated Microsoft.Azure.Storage to Azure.Storage.Blobs

* Remove and order usings

* Do not fetch BlobProperties before uploading a new file.

* Save an api call by calling GetPropertiesAsync and catching an error instead of calling Exists first

* Formatted files

* Verified ContentLength is the correct blob property for file-size

* Use a generic Exception catch for file validation

* Added a catch all to the GetBlobCertificateAsync in case something throws

* Remove and sort using

* Changes after running dotnet-format

* Remove checks for CanGenerateSasUri
This commit is contained in:
Daniel James Smith
2021-12-22 19:47:35 +01:00
committed by GitHub
parent bb34de74cb
commit 355bf2127b
6 changed files with 181 additions and 177 deletions

View File

@ -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<X509Certificate2> GetBlobCertificateAsync(CloudStorageAccount cloudStorageAccount,
string container, string file, string password)
public async static Task<X509Certificate2> 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;

View File

@ -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);
}
}