mspnp/cloud-design-patterns

Valet Key Pattern : AuthorizationPermissionMismatch: request is not authorized to perform this operation using this permission

eliassal opened this issue · 8 comments

I am following instructions for the Valet Key Pattern sample at https://github.com/mspnp/cloud-design-patterns/tree/main/valet-key,
I run the web application, then run the client, SAS is generated but in the client terminal I get

Press any key to run the sample...
Write operation failed for SAS https://valetkeypatternsierac.blob.core.windows.net:443/valetkeysample/d07801e1-cc87-4f60-8f9c-4be2d1471562?skoid=8ef0c0eb-860b-47a4-8ae8-8dcb7463dd20&sktid=6799c70e-3ceb-4e88-af13-8f6c565fd4a5&skt=2024-01-23T14%3A46%3A34Z&ske=2024-01-24T14%3A46%3A34Z&sks=b&skv=2023-01-03&sv=2023-01-03&st=2024-01-23T14%3A41%3A49Z&se=2024-01-23T14%3A51%3A49Z&sr=b&sp=w&sig=qZEVi6KsQCLs3gcDwe3VyR2PlbPfTfHvRFdXZA55uug%3D
Additional error information: This request is not authorized to perform this operation using this permission.
RequestId:f14b5518-001e-0000-6b0a-4ecd6f000000
Time:2024-01-23T14:46:49.8926542Z
Status: 403 (This request is not authorized to perform this operation using this permission.)
ErrorCode: AuthorizationPermissionMismatch

Content:
?<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.
RequestId:f14b5518-001e-0000-6b0a-4ecd6f000000
Time:2024-01-23T14:46:49.8926542Z</Message></Error>

Headers:
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: f14b5518-001e-0000-6b0a-4ecd6f000000
x-ms-client-request-id: afc67a89-c3ed-4544-949f-490f8c40f034
x-ms-version: 2023-01-03
x-ms-error-code: AuthorizationPermissionMismatch
Date: Tue, 23 Jan 2024 14:46:49 GMT
Content-Length: 279
Content-Type: application/xml

Done. Press any key to exit...

As you can notice, here is the ouput in the web app terminal

Building...
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:10194
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Projects\AzureDevOpsProjects\DesignPatternsAzure\cloud-design-patterns\valet-key\ValetKey.Web
info: ValetKey.Web.Controllers.SasController[0]
      Blob Uri: https://valetkeypatternsierac.blob.core.windows.net/valetkeysample/6f9958d3-XXXXXXXXXXXXX- Shared Access Signature: skoid=8ef0c0eb-860b-47a4-8ae8-8dcb7463dd20&sktid=6799c70e-3ceb-4e88-af13-8f6c565fd4a5&skt=XXXXXXX6%3A50Z&ske=2024-01-24T14%3A36%3A50Z&sks=b&skv=2023-01-03&sv=2023-01-03&st=2024-01-23T14%3A32%3A04Z&se=2024-01-23T14%3A42%3A04Z&sr=b&sp=w&sig=lEAxJtxLrNGSxWwISiusKJ01NpZ9Hxc7Tf0IRSdHwjw%3D

So why it is not allowing and says AuthorizationPermissionMismatch: This request is not authorized to perform this operation using this permission

I just ran the sample end to end following the instructions exactly, and it worked.

Press any key to run the sample...
Blob uploaded successful: ef8e4bcc-d974-4739-8ad1-824467b27117

Done. Press any key to exit...

I was not able to get my setup to behave like yours.

Can you verify that your account supports Entra ID delegated SaS tokens?
image

Also verify that you added your user with the correct RBAC permissions?

image

Dear @ckittel , yes storage key access is enabled
image

Regarding the 2nd comment, I am not sure which user you are refering to? The code, I understand generated a SAS through the web application so which user you are asking about?

I created the storage account with my super user, and I have all permissions as you can notice hereunder with which I created the storage account, but really not able to understand where in the code uses an RBAC or account.

image

This scenario uses Entra ID delegated SAS tokens. It uses the managed identity of the web server to generate the token that the client will use. When you are running local, it uses your az account show or visual studio configured azure identity for that identity. If you deployed this to azure it would use the system or user assigned identity of the service.

Being a super user in azure is not sufficient, as SAS tokens are a data plane operation and not a control plane operation. That executing account needs the data plane permission.

The instructions call out this step. Please review them again. Thanks.

OK, following your comments, I did the following, in terminal, I issued
az login
used my user
also, I added "Storage Blob Data Owner" to my super user
and hop it worked and Blob uploaded successful.
But here I am confused with the scenario. It is indicated

This example shows how a client application can obtain a shared access signature with the necessary permissions to write directly to blob storage. For simplicity, this sample focuses on the mechanism to obtain and consume a valet key and does not show how to implement authentication or secure communications.

Which should allow us avoiding having user accounts for everybody that we want to give them the possibility to upload a file? Does this mean that for any one we want him to upload should run the web application with a user declared in Entra on their local machine? Can you please confirm?

Can you please tell me how the .net web app choses my azure identity to run itself? is it something inside the code that tells the web to use Azure Entra ID? Thanks

As called out in the deployment guide, the code uses DefaultAzureCredential which is a "smart" fallback credential that looks at where the code is running from and tries a series of configurations until it hits one that works. That is ideal because the same code then works local and on Azure, without needing to make special conditional logic.

The client NEVER sees this identity, this is only the privileged web server which is handing out these tokens. If it wasn't for a managed identity, it would instead need to use account keys (which are not desirable to use, since they require rotation).

Which should allow us avoiding having user accounts for everybody that we want to give them the possibility to upload a file?

Yes, exactly. This is using one Microsoft Entra account that has the correct permissions on the storage account (instead of key-based permission on the storage account), to hand out SaS tokens. Think if it this way, the Web project needs to generate SaS tokens, and to do that it needs a secret. Either it needs the signing key from the Storag account service (not ideal) or better, it can use SAS tokens signed with delegated auth, so it's identity based not key based from the Web project.

The client code does NOT know about any of this. It has no meaningful knowledge of how any SaS token was generated.

So, if you had a Web server doing the work of the "Web" project, then that would be hosted in Azure (Web Apps, for example), which has a System managed identity. That system managed identity has the role to be able to do hand out the SaS tokens (on behalf of itself) to those needing to upload. It's the exact same as the Web server using the storage account key to do this work, but using its identity instead of a pre-shared secret. The identity of "client" does not matter. For example, you could spin up a brand new VM, and run the client, no azure login, etc. The client doesn't have an identity, just the server.

So many thanks for your help, got it, I went through the explanantion at https://learn.microsoft.com/en-us/dotnet/azure/sdk/authentication/?tabs=command-line#exploring-the-sequence-of-defaultazurecredential-authentication-methods
all is clear for me now. Thanks again

You're welcome. Thanks for reaching out to learn! Best wishes.