1
votes

I created an App Registration in Azure Active Directory and added the API permission to access Azure storage.

I also created a user and app role assignment as follows:

New-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $servicePrincipal.ObjectId -Id ([Guid]::Empty)

I gave the user the Storage Blob Data Contributor role in Azure portal. I then got an access token from this method:

public void acquireToken(android.app.Activity activity,
                     String resource,
                     String clientId,
                     @Nullable String redirectUri,
                     @Nullable String loginHint,
                     @NonNull com.microsoft.aad.adal.AuthenticationCallback<com.microsoft.aad.adal.AuthenticationResult> callback)

The clientId is the app with the permission to access storage. The redirect URI is the one I set for the app in the portal. I've tried two resource IDs. I send that token up as an Authentication: Bearer header.

It returns the error "Audience validation failed. Audience did not match" if the resource ID I pass to acquireToken is "https://<>.blob.core.windows.net/"

It returns the error "The specified container does not exist" if the resource ID is "https://storage.azure.com/".

I'm using Retrofit to perform the PUT operation.

public static final String CONTENT_TYPE_TEXT_PLAIN_HEADER = "Content-Type: text/plain; charset=UTF-8";
public static final String X_MS_VERSION = "x-ms-version: 2017-11-09";
public static final String X_MS_DATE = "x-ms-date";
public static final String X_MS_BLOB_CONTENT = "x-ms-blob-content-disposition: attachment; filename=\"fname.ext\"";
public static final String X_MS_BLOB_TYPE = "x-ms-blob-type: BlockBlob";
public static final String X_MS_META_M1 = "x-ms-meta-m1: v1";
public static final String X_MS_META_M2 = "x-ms-meta-m2: v2";

@Headers({CONTENT_TYPE_TEXT_PLAIN_HEADER,
        X_MS_VERSION,
        X_MS_BLOB_CONTENT,
        X_MS_BLOB_TYPE,
        X_MS_META_M1, X_MS_META_M2})
@PUT("/blob1")
Call<Void> putBlob(@Header(AUTHORIZATION) String bearerToken,
                     @Header(X_MS_DATE) String date,
                     @Body String putBody);
1

1 Answers

2
votes

It returns the error "Audience validation failed. Audience did not match" if the resource ID I pass to acquireToken is https://<>.blob.core.windows.net/

Remove that trailing slash from https://<>.blob.core.windows.net/, it should now match what Azure AD expects for audience.

From https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-app#azure-storage-resource-id -

Azure Storage resource ID

An Azure AD resource ID indicates the audience for which a token that is issued can be used to provide access to an Azure resource. In the case of Azure Storage, the resource ID may be specific to a single storage account, or it may apply to any storage account. The following table describes the values that you can provide for the resource ID:

https://<account>.blob.core.windows.net