I managed to get the below code to work (complete code here) to use Azure managed identity to authenticate (via Visual Studio) and have access to Azure storage account without using credentials.
const string storageResource = "https://storage.azure.com/";
var authResult = await azureServiceTokenProvider.GetAuthenticationResultAsync(storageResource, cancellationToken: cancellationToken);
The code managed to find my user logged in to Visual Studio and uses it to get the token and all goes well.
However, this code is executed as part of a library integration tests in an Azure DevOps build pipeline.
I found the service principal created when I created the service connection to Azure in Azure DevOps and gave it the same Storage Blob Data Contributor
role hoping that Azure DevOps would use it to run the code but had no success.
So my question is:
How do I get code that runs in Azure DevOps build pipeline to be able to authenticate using the AzureServiceTokenProvider
?
BTW, the error message:
Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException : Parameters: Connection String: [No connection string specified], Resource: https://storage.azure.com/, Authority: . Exception Message: Tried the following 3 methods to get an access token, but none of them worked. Parameters: Connection String: [No connection string specified], Resource: https://storage.azure.com/, Authority: . Exception Message: Tried to get token using Managed Service Identity. Access token could not be acquired. Failed after 5 retries. MSI ResponseCode: BadRequest, Response: {"error":"invalid_request","error_description":"Identity not found"} Parameters: Connection String: [No connection string specified], Resource: https://storage.azure.com/, Authority: . Exception Message: Tried to get token using Visual Studio. Access token could not be acquired. Visual Studio Token provider file not found at "C:\Users\VssAdministrator\AppData\Local.IdentityService\AzureServiceAuth\tokenprovider.json" Parameters: Connection String: [No connection string specified], Resource: https://storage.azure.com/, Authority: . Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. ERROR: Please run 'az login' to setup account.
TearDown : System.NullReferenceException : Object reference not set to an instance of an object.
When you create a service connection in Azure DevOps you are presented with (as of writing) 4 options.
A publish profile is an Azure App Service specific authentication mechanism that lets you publish via Kudu.
Manage identities are somewhat mislabeled. They are used to allow a VM running your Azure pipelines to act as the managed identity of that VM (you then give this managed identity access to the resources you want it to be able to access in the Azure Portal). This is somewhat backwards from how the other authentication methods work but I guess it makes sense when you are hosting your own Azure pipelines on VMs in Azure. This option has this caveat.
The AzureServiceTokenProvider
will only work from within an environment that expose the MSI_ENDPOINT
(aka IDENTITY_ENDPOINT
). Hosted Azure DevOps pipelines are not such environments.
Service principals is what you will be using in all likelihood.
Service principals come in two flavours automatic and manual. Again with the mislabeling. There's actually nothing automatic with the automatic option the only thing that happens is that it provisions the service principal in your Azure AD for you. It will grant the service principal the contributor role at the subscription level (which means full access to everything in the subscription except access control). You should not grant service principals that kind of access. It is excessive. Remember that you service principals are just protected by credentials, that if they leak, they allow anyone to do irreparable harm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With