Search code examples
c#asp.net-mvcazureazure-media-services

Azure Media Service - generate new AES encryption token for playback


I am working on open source community project Azure Media Services Upload and Play Videos in MVC since 2015. I was not using any delivery encryption earlier, so I started working on AES.

In all the source code/samples by Azure Media Services Team, i noticed test token was being generated just after uploading the content and this works well in my case too. But, how do I generate test token next time onward for playback?

What I understood is that, we need token each time player requests playback. Technically, player creates a request to key service provider and received updated token.

So to get updated token, I tried couple of ways n not able to fix this, i see error "A ContentKey (Id = '...', Type = 'EnvelopeEncryption') which contains the same type already links to this asset".

enter image description here

This looks like a valid error message because key of type EnvelopeEncryption was already added and associated with asset after uploading content, and upon requesting again this pops-up.

The code given below is copied from here.

    public ActionResult Index()
    {
        var model = new List<VideoViewModel>();

        var videos = db.Videos.OrderByDescending(o => o.Id).ToList();
        foreach (var video in videos)
        {
            var viewModel = new VideoViewModel();
            viewModel.Id = video.Id;
            viewModel.EncodedAssetId = video.EncodedAssetId;
            viewModel.IsEncrypted = video.IsEncrypted;
            viewModel.LocatorUri = video.LocatorUri;

            // If encrypted content, then get token to play
            if (video.IsEncrypted)
            {
                IAsset asset = GetAssetById(video.EncodedAssetId);
                IContentKey key = CreateEnvelopeTypeContentKey(asset);
                viewModel.Token = GenerateToken(key);
            }

            model.Add(viewModel);
        }

        return View(model);
   }

Above method calls media service key service provider.

How do I fix this?


Solution

  • You can look into AMS explorer sources

    when you creating a restriction policy yo are doing something like this:

    //Initilizing ContentKeyAuthorizationPolicyRestriction
      ContentKeyAuthorizationPolicyRestriction restriction = new ContentKeyAuthorizationPolicyRestriction
      {
          Name = "Authorization Policy with Token Restriction",
          KeyRestrictionType = (int)ContentKeyRestrictionType.TokenRestricted,
          Requirements = TokenRestrictionTemplateSerializer.Serialize(restrictionTemplate)};
    
      restrictions.Add(restriction);
    
      //Saving IContentKeyAuthorizationPolicyOption on server so it can be associated with IContentKeyAuthorizationPolicy
      IContentKeyAuthorizationPolicyOption policyOption = objCloudMediaContext.ContentKeyAuthorizationPolicyOptions.Create("myDynamicEncryptionPolicy", ContentKeyDeliveryType.BaselineHttp, restrictions, String.Empty);
      policy.Options.Add(policyOption);
    
      //Saving Policy
      policy.UpdateAsync();
    

    Key field here is irements = TokenRestrictionTemplateSerializer.Serialize(restriction.Requirements)};

    You need to fetch corresponding asset restriction you created first place and desirialize TokenRestriction Template back with

    TokenRestrictionTemplate tokenTemplate = TokenRestrictionTemplateSerializer.Deserialize(tokenTemplateString);
    

    Based on what type of key and encryption you use

                                if (tokenTemplate.PrimaryVerificationKey.GetType() == typeof(SymmetricVerificationKey))
                                {
                                    InMemorySymmetricSecurityKey tokenSigningKey = new InMemorySymmetricSecurityKey((tokenTemplate.PrimaryVerificationKey as SymmetricVerificationKey).KeyValue);
                                    signingcredentials = new SigningCredentials(tokenSigningKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest);
                                }
                                else if (tokenTemplate.PrimaryVerificationKey.GetType() == typeof(X509CertTokenVerificationKey))
                                {
                                    if (signingcredentials == null)
                                    {
                                        X509Certificate2 cert = DynamicEncryption.GetCertificateFromFile(true).Certificate;
                                        if (cert != null) signingcredentials = new X509SigningCredentials(cert);
                                    }
                                }
                                JwtSecurityToken token = new JwtSecurityToken(issuer: tokenTemplate.Issuer, audience: tokenTemplate.Audience, notBefore: DateTime.Now.AddMinutes(-5), expires: DateTime.Now.AddMinutes(Properties.Settings.Default.DefaultTokenDuration), signingCredentials: signingcredentials, claims: myclaims);
                                JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
                                string token = handler.WriteToken(token);