How do I access Azure AI Video Indexer ARM API Programatically?

Matthew D Suddaby 5 Reputation points
2023-11-12T21:09:59.3066667+00:00

I'm quite lost here. For some reason, almost all documentation relating to my problems are bringing up a 404.

I'm trying to programmatically access Azure AI Video Indexer. I've downloaded (and slightly modified) the ARM API example from the github here:
https://github.com/Azure-Samples/media-services-video-indexer/tree/master/API-Samples/C%23/ArmBased

And set up my Azure resources. I created a Video Indexer service, as well an Entra ID app registration with the following permissions:
User's image

When I try to use the code to get an account access token (code):

   public static class AccountTokenProvider
   {
       private static readonly string clientId = "removed";
       private static readonly string clientSecret = "removed";
       private static readonly string tenantId = "removed";

       public static async Task<string> GetArmAccessTokenAsync(CancellationToken ct = default)
       {
           var tokenRequestContext = new TokenRequestContext(new[] { $"{Consts.AzureResourceManager}/.default" });

           var options = new TokenCredentialOptions
           {
               AuthorityHost = new Uri($"https://login.microsoftonline.com/{tenantId}")
           };

           var credential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);

           //var tokenRequestResult = await new DefaultAzureCredential().GetTokenAsync(tokenRequestContext, ct);
           var tokenRequestResult = await credential.GetTokenAsync(tokenRequestContext, ct);
           return tokenRequestResult.Token;
       }

       public static async Task<string> GetAccountAccessTokenAsync(string armAccessToken, ArmAccessTokenPermission permission = ArmAccessTokenPermission.Contributor, ArmAccessTokenScope scope = ArmAccessTokenScope.Account, CancellationToken ct = default)
       {
           var accessTokenRequest = new AccessTokenRequest
           {
               PermissionType = permission,
               Scope = scope
           };

           try
           {
               var jsonRequestBody = JsonSerializer.Serialize(accessTokenRequest);
               Console.WriteLine($"Getting Account access token: {jsonRequestBody}");
               var httpContent = new StringContent(jsonRequestBody, System.Text.Encoding.UTF8, "application/json");

               // Set request uri
               var requestUri = $"{Consts.AzureResourceManager}/subscriptions/{Consts.SubscriptionId}/resourcegroups/{Consts.ResourceGroup}/providers/Microsoft.VideoIndexer/accounts/{Consts.ViAccountName}/generateAccessToken?api-version={Consts.ApiVersion}";
               var client = HttpClientUtils.CreateHttpClient();
               client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", armAccessToken);

               var result = await client.PostAsync(requestUri, httpContent, ct);
               Console.WriteLine(await result.Content.ReadAsStringAsync());
               result.EnsureSuccessStatusCode();
               var jsonResponseBody = await result.Content.ReadAsStringAsync(ct);
               Console.WriteLine($"Got Account access token: {scope} , {permission}");
               return JsonSerializer.Deserialize<GenerateAccessTokenResponse>(jsonResponseBody)?.AccessToken!;
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.ToString());
               throw;
           }
       }

   }

I get a 403 forbidden error.

{"error":{"code":"AuthorizationFailed","message":"The client '[shows enterprise app id]' with object id '[exact same enterprise app id here]' does not have authorization to perform action 'Microsoft.VideoIndexer/accounts/generateAccessToken/action' over scope '/subscriptions/[correct subscription id]/resourcegroups/[correct resource group name]/providers/Microsoft.VideoIndexer/accounts/[correct AI video indexer account name]' or the scope is invalid. If access was recently granted, please refresh your credentials."}}

Any thoughts? I'm totally stumped here.

Azure AI Video Indexer
Azure AI Video Indexer
An Azure video analytics service that uses AI to extract actionable insights from stored videos.
47 questions
{count} vote

1 answer

Sort by: Most helpful
  1. Matt Doyle 20 Reputation points
    2023-11-22T04:00:18.75+00:00

    After a lot of trial and error, I managed to get this working.

    For me, it was because I hadn't created the correct role assignment. It's also non-obvious how to do it.

    Steps that fixed it for me:

    • Create the app registration in the portal (Microsoft Entra ID > App registrations > New registration) if not already done.
    • Copy the name of the app. You'll need it later!
    • Still in the portal, go to the Video Indexer resource that you created.
    • Go to Access control (IAM) > Role assignments > Add > Add role assignment.
    • Select Privileged administrator roles > Contributor.
    • Under Members, select "User, group, or service principal", then click Select members.
    • Here's the important bit: A right-hand pane appears with a list of users, but it doesn't include your app name. However, if you search for your app name, it appears. Click it, then click Select.
    • Click Review + assign.

    You've now set up the correct role assignment for your app and the video indexer resource.

    Once I'd done that, I could successfully generate the video indexer access token using the app's bearer token.

    4 people found this answer helpful.