Skip to content

Commit

Permalink
feat: Support azure blob storage auth with managed identity.
Browse files Browse the repository at this point in the history
  • Loading branch information
mariojsnunes committed Apr 14, 2024
1 parent f59edd1 commit daf2e03
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Extensions.Options;
using OrchardCore.Environment.Shell;
using OrchardCore.Environment.Shell.Removing;
using OrchardCore.FileStorage.AzureBlob;
using OrchardCore.Modules;

namespace OrchardCore.Media.Azure
Expand Down Expand Up @@ -47,7 +48,7 @@ public override async Task ActivatingAsync()

try
{
var _blobContainer = new BlobContainerClient(_options.ConnectionString, _options.ContainerName);
var _blobContainer = BlobContainerClientFactory.Create(_options);
var response = await _blobContainer.CreateIfNotExistsAsync(PublicAccessType.None);

_logger.LogDebug("Azure Media Storage container {ContainerName} created.", _options.ContainerName);
Expand All @@ -70,7 +71,7 @@ public override async Task RemovingAsync(ShellRemovingContext context)

try
{
var _blobContainer = new BlobContainerClient(_options.ConnectionString, _options.ContainerName);
var _blobContainer = BlobContainerClientFactory.Create(_options);

var response = await _blobContainer.DeleteIfExistsAsync();
if (!response.Value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Extensions.Options;
using OrchardCore.Environment.Shell;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.FileStorage.AzureBlob;

namespace OrchardCore.Media.Azure
{
Expand Down Expand Up @@ -37,6 +38,9 @@ public void Configure(MediaBlobStorageOptions options)
options.ConnectionString = section.GetValue(nameof(options.ConnectionString), string.Empty);
options.CreateContainer = section.GetValue(nameof(options.CreateContainer), true);
options.RemoveContainer = section.GetValue(nameof(options.RemoveContainer), false);
options.IdentityClientId = section.GetValue(nameof(options.IdentityClientId), string.Empty);
options.AuthenticationType = section.GetValue(nameof(options.AuthenticationType), BlobAuthenticationType.ConnectionString);
options.StorageAccountName = section.GetValue(nameof(options.StorageAccountName), string.Empty);

var templateOptions = new TemplateOptions();
var templateContext = new TemplateContext(templateOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace OrchardCore.FileStorage.AzureBlob;

public enum BlobAuthenticationType
{
ConnectionString = 0,
ManagedIdentity = 1,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using Azure.Identity;
using Azure.Storage.Blobs;

namespace OrchardCore.FileStorage.AzureBlob;

public class BlobContainerClientFactory
{
public static BlobContainerClient Create(BlobStorageOptions options)
{
if (options.AuthenticationType == BlobAuthenticationType.ConnectionString)
{
return new BlobContainerClient(options.ConnectionString, options.ContainerName);
}
else if (options.AuthenticationType == BlobAuthenticationType.ManagedIdentity && !String.IsNullOrWhiteSpace(options.IdentityClientId))
{
return new BlobContainerClient(GetStorageAccountUri(options.StorageAccountName), new ManagedIdentityCredential(options.IdentityClientId));
}
else
{
return new BlobContainerClient(GetStorageAccountUri(options.StorageAccountName), new DefaultAzureCredential());
}
}

private static Uri GetStorageAccountUri(string storageAccountName)
{
return new Uri($"https://{storageAccountName}.blob.core.windows.net");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public BlobFileStore(BlobStorageOptions options, IClock clock, IContentTypeProvi
_clock = clock;
_contentTypeProvider = contentTypeProvider;

_blobContainer = new BlobContainerClient(_options.ConnectionString, _options.ContainerName);
_blobContainer = BlobContainerClientFactory.Create(_options);

if (!string.IsNullOrEmpty(_options.BasePath))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,20 @@ public abstract class BlobStorageOptions
/// The base directory path to use inside the container for this stores contents.
/// </summary>
public string BasePath { get; set; }

/// <summary>
/// The Azure storage account name. Required for Identity authentication type.
/// </summary>
public string StorageAccountName { get; set; }

/// <summary>
/// The authentication type.
/// </summary>
public BlobAuthenticationType AuthenticationType { get; set; }

/// <summary>
/// The Identity Client Id. Required for ManagedIdentity authentication type.
/// </summary>
public string IdentityClientId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" />
<PackageReference Include="Microsoft.Extensions.Azure" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit daf2e03

Please sign in to comment.