Reputation: 220
I have a multitenant application which stores certain custom assemblies for each tenant in blobs in their Azure storage account. These assemblies contain custom code to run reports for the specific tenant who is logged in.
The most straightforward approach I think would be to have the Azure function download the DLLs into it's local workspace and load & execute from there (we use MEF to do this).
Is it possible for an Azure function or a webapp to execute code directly from that blob container?
Azure websites can run out of Azure storage so curious if an azure function can dynamically load and run those assemblies remotely. Obviously, there are security risks to doing so but that what would be the workarounds?
Also, Azure functions actually execute code out of blob storage I discovered while chatting with an Azure rep on a support call though I don't know how they do so and haven't done a POC.
Just looking if this is even possible before running POCs.
Upvotes: 3
Views: 752
Reputation: 4730
You can simply download a blob from a blob storage as byte array, load it as assembly, and use it.
This is a naive implementation of a static function:
[FunctionName("LoadDll")]
public static async Task<object> RunDll(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
ILogger log)
{
var containerName = "dlls";
var filename = "ClassLibrary1.dll";
// Connect to Storage Account (in case of local development – Azurite)
var blobServiceClient = new BlobServiceClient("AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;");
var blobContainerClient = blobServiceClient.GetBlobContainerClient(containerName);
var blobClient = blobContainerClient.GetBlobClient(filename);
// Read the assembly file from the Blob Storage
var stream = await blobClient.OpenReadAsync();
using var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
// Read it to a byte array
var assemblyBytes = memoryStream.ToArray();
// Load the assembly from the byte array
var assembly = Assembly.Load(assemblyBytes);
// Find a class
var class1Type = assembly.GetType("ClassLibrary1.Class1");
// Find a method in the class
var method = class1Type.GetMethod("GetInt");
// Instantiate the class
var obj = Activator.CreateInstance(class1Type);
// Call the method
var result = method.Invoke(obj, null);
return result;
}
I created a class library project ClassLibrary1
and defined a class:
namespace ClassLibrary1
{
public class Class1
{
public int GetInt()
{
return 1;
}
}
}
Then I uploaded it to Azurite (Local Storage Account Emulator) to blob container dlls
:
When I run the Azure Function app and open the URL http://localhost:7208/api/LoadDll
in browser, the result is:
Upvotes: 3