Reputation: 11
I want to access the Blob Storage from an Azure Function. I have multiple Azure Functions and want to manage all permissions at one place.
Therefore I have created an App-Registration AR1. This App-Registration I gave user_impersonation permission to Azure-Storage. And in the Access Control (AIM) of the Blob Storage I assigned the role "Storage Blob Data Contributor" to the Enterprise Application of the AR1. In my Azure function I enabled the MSI and in the Authentication I created the Microsoft Identity Provider for the App Registration I created earlier. To link my Azure Function with AR1 I create user-defined role "blob storage contributor" and assigned this role to the MSI of the Azure Function in the corresponding Enterprise Application for AR1.
The Azure function in the code accesses Blob Storage with DefaultAzureCredentials(). So my idea - the Azure Function fetches a token from the Identity Provider with its MSI. The token claims that it was created for the App-Registration AR1 and the Azure Function then accesses the Blob Storage with that AR1-token "as the App-Registration AR1". The AR1 has the role "Storage Blob Data Contributor" and is allowed to read the blobs - so should my Function too. Unfortunately it does not work - I got the error "Exception occurs: This request is not authorized to perform this operation". Where is an error in my procedure? Or do I have to do something extra?
Upvotes: 1
Views: 5301
Reputation: 11
I have found a solution. It seems it is not possible for the MSI flow when using DefaultAzureCredential() (I have not created any environment variables so that the MSI flow is used by DefaultAzureCredential()). It seems that my Azure Functions need to log in directly into the app registration. So, the application service principal flow via Environment needs to be activated for DefaultAzureCredential(). It can / must be done through Environment variables: AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_CLIENT_SECRET. To do this, I had to create a Secret in the app registration AR1 (e.g. with the name MyFunctionSecret) and create these three variables in my Azure function's Configuration:
AZURE_CLIENT_ID = %App Registration Client ID%
AZURE_TENANT_ID = %TENANT ID of my function%
AZURE_CLIENT_SECRET = %MyFunctionSecret%
Now it works as desired. But I am not happy. Instead of SharedAccessKey / ConnectionString I have now the MyFunctionSecret which can expire and must be renewed / rotated too. I hoped with MSI's I could avoid this complicated rotation (with Azure Vault and ...) and all security would be managed by Azure for me.
Upvotes: 0
Reputation: 1506
By using App Registration with a managed identity. This helps to manage permissions for all Azure Functions in one place.
Steps to setup Managed Identity
.
Create an App Registration
in Azure Active Directory and grant it the necessary permissions to access Blob Storage.
Enable a managed identity for your Azure Function.
Grant the managed identity access to the App Registration
in Azure AD.
Use the Azure SDK for .NET to authenticate to Blob Storage using the managed identity.
var cred = new DefaultAzureCredential();
var BlbSvcClient = new BlobServiceClient(new Uri("https://<your-storage-account-name>.blob.core.windows.net"), cred);
Access to Blob storage for the App
Managed identity to Function App
For further information refer to MSDoc1 and MSDoc2.
Upvotes: 0