I am using a .net core webapp mvc to get data from a blob in a storage account using oauth tokens, but I am getting an authorization not permitted error. Previously, I tried to display the access token in the app, and there were no issues. I am also able to signin and signout without issues
In Azure, I have an app registration created where I have added custom openid endpoints for signin and signout that tally with my environment. I also added user_impersonation API permission for Azure storage to the app registration.
In Azure Storage Account, I added both reader and Azure blob Data Reader roles to the app object.
In my appsettings.json, I have a variable "AzureAD" that contains the regular parameters, such as tenantid, clientid, cleintsecret, instance, callbackpath,etc.
In my launchsetting.json, the applicationurl is same as what was used in Azure portal
Ordinarily, this should work. I just need to be able to view content of the blob from my app.
I have looked through Microsoft Learn but I can't seem to get a solution.
Find attached the screenshot of the error messages.
If I can just know some of the possible causes of this particular error message, it will really help as I have done a lot of search but they keep pointing me to role assignment, which can not be the issue here.
Let me also add that I am using the TokenAcquisitionTokenCredential class, while it is deprecated it is still supported and should not be the reason for the runtime error.
I am expecting to see content of the blob displayed in my browser. The code segment below is where it is really happening:
public async Task<IActionResult> Index()
{
string[] scopes = new string[] { "https://storage.azure.com/user_impersonation" };
Uri blobUri = new Uri("https://xxxxxxxxxx.blob.core.windows.net/data/testfile.txt");
TokenAcquisitionTokenCredential credential = new TokenAcquisitionTokenCredential(tokenAcquisition);
BlobClient blobClient = new BlobClient(blobUri, credential);
MemoryStream ms = new MemoryStream();
blobClient.DownloadTo(ms);
ms.Position = 0;
StreamReader _reader = new StreamReader(ms);
string str = _reader.ReadToEnd();
ViewBag.content = str;
return View();
}
Find below the error messages that was displayed
After a successful signin, this error displayed rather than blob content:
Screenshot of the error message:
Screenshot of the error message after using OnBehalfOfCredential based on the first answer provided:
Firstly, we have the official document here which demonstrating to use DefaultAzureCredential
to authenticate the BlobServiceClient, codes looks like below.
public BlobServiceClient GetBlobServiceClient(string accountName)
{
BlobServiceClient client = new(
new Uri($"https://{accountName}.blob.core.windows.net"),
new DefaultAzureCredential());
return client;
}
It also mentioned that
If you know exactly which credential type you'll use to authenticate users, you can obtain an OAuth token by using other classes in the Azure Identity client library for .NET
Then I tried to find all TokenCredential
implements but I didn't find the TokenAcquisitionTokenCredential
you used in your code. So that you might use a custom TokenCredential
.
My suggestions in my side is firstly using the DefaultAzureCredential
to complete the connection to Azure Storage. Since we already have an Azure AD application granting required API permission. We can set Environment Variable for it to get authenticated. AZURE_CLIENT_ID AZURE_TENANT_ID AZURE_CLIENT_SECRET
. Then using the code at the beginning to test the connection.
If you don't think this is a good option and you still want to use the access token to get a TokenCredential
, I think we can use the OnBehalfOfCredential.
var tenantId = "xxxx";
var clientId = "xxxx";
var clientSecret = "xxxx";
var onBehalfOfCredential = new OnBehalfOfCredential(tenantId, clientId, clientSecret, "{token_we_get_from_tokenAcquisition}");
BlobServiceClient client = new(
new Uri($"https://accountName.blob.core.windows.net"),
onBehalfOfCredential);