17 Replies Latest reply: Mar 26, 2014 6:30 PM by marknz RSS

    Problem with custom Authentication Token

    _sebest_ Community Member

      Hello,

       

      I'm trying to use custom authentication token, but i don't manage to get the OSMF based player to send the token to the server.

       

      I will describe the whole process that we use to achieve this.

       

      the java code to create the policy for custom authentication:

       

      import com.adobe.flashaccess.sdk.policy.LicenseServerInfo;
      import com.adobe.flashaccess.sdk.policy.Policy;
      import com.adobe.flashaccess.sdk.policy.PolicyException;
      import com.adobe.flashaccess.sdk.policy.ServerInfo.AuthenticationType;
      import com.adobe.flashaccess.sdk.rights.PlayRight;
      import com.adobe.flashaccess.sdk.rights.Right;
      
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.ArrayList;
      import java.util.List;
      
      public class CreatePolicy
      {
          public static void main(String[] args) {
              Policy policy = new Policy(false);
              policy.setName("custom_policy");
              policy.setLicenseServerInfo(new LicenseServerInfo(AuthenticationType.Custom));
      
          PlayRight play = new PlayRight();
          List<Right> rightsList = new ArrayList<Right>();
          rightsList.add(play);
              policy.setRights(rightsList);
      
              try
              {
                  // Serialize the policy                                                                                                                                                                                                                                                                                                                                                                                                      
                  byte[] policyBytes = policy.getBytes();
                  System.out.println("Created policy with ID: " + policy.getId());
                  // Write policy to a file.  Alternatively, the policy could be stored in a database.                                                                                                                                                                                                                                                                                                                                         
                  FileOutputStream out = new FileOutputStream("custom.pol");
                  out.write(policyBytes);
                  out.close();
              } catch (PolicyException e) {
                  // The policy could not be created, because required fields were not set.                                                                                                                                                                                                                                                                                                                                                    
                  e.printStackTrace();
              } catch (IOException e) {
                  // Error writing policy to file                                                                                                                                                                                                                                                                                                                                                                                              
                  e.printStackTrace();
              }
          }
      }
      

       

      Here is the output of Adobe Policy Manager for this policy:

       

      Adobe(R) Flash Access Policy Manager
      version 2.0.2.0061
      =======================
      Policy Report:
      =============
      
      Policy ID: 2B765152-4833-3E5E-8C78-B2488E4C987C
      Policy Name: custom_policy
      Revision: 1
      
      License Server Authentication: custom
      
      Unlimited License Caching
      
      Right: Play
      

       

      Then we modify this policy to add some metadata and use it to package a standard mp4 file.

       

      Here is the output of Adobe(R) Flash Access Media Packager for this packaged mp4 file:

       

      Adobe(R) Flash Access Media Packager
      version 2.0.2.0061
      =======================
      Source file: mp4_h264_aac_fa2-1326491966.mp4
      License Server: http://lic.dev.int.secret.net
      License ID: 9EC8E136-9D2D-3D12-B042-7EC97212C1D3
      Content ID: 4e6f6bbddede83536f000000.4f10b739dede83376c000000
      Packager: CN=MyCorp-PKG-20111123,OU=Adobe Flash Access,OU=Packager,O=Adobe Systems Incorporated,C=US
      Packaging time: Fri Jan 13 23:59:25 CET 2012
      Policies:
      
      
      Policy ID: 2B765152-4833-3E5E-8C78-B2488E4C987C
      Policy Name: custom_policy
      Revision: 2
      
      License Server Authentication: custom
      
      License Caching Duration: 1440 minutes (1 day)
      
      Right: Application Defined Right
          media_id =
              4f10b739dede83376c000000
          user_id =
              4e6f6bbddede83536f000000
      Right: Play
      
      CustomProperties: 
          media_id =
              4f10b739dede83376c000000
          user_id =
              4e6f6bbddede83536f000000
      
      
      SUCCESS
      

       

      The file is stored on a standard HTTP server.

       

      Here is the code of the OSMF 1.6 based video player:

       

      package
      {
           import flash.display.Sprite;
           import flash.utils.ByteArray;
      
           import org.osmf.events.MediaPlayerStateChangeEvent;
           import org.osmf.media.DefaultMediaFactory;
           import org.osmf.media.MediaElement;
           import org.osmf.media.MediaPlayerSprite;
           import org.osmf.media.MediaPlayerState;
           import org.osmf.media.MediaResourceBase;
           import org.osmf.media.URLResource;
           import org.osmf.metadata.MetadataNamespaces;
           import org.osmf.net.StreamingURLResource;
           import org.osmf.traits.DRMTrait;
           import org.osmf.traits.MediaTraitType;
           import org.osmf.events.DRMEvent;
           import org.osmf.traits.DRMState;
      
           public class MyPlayer extends Sprite
           {
                private var protectedMP4:String = "http://secret.net/mp4_h264_aac_fa2-1326491966.mp4";
                private var player:MediaPlayerSprite = null;
                private var streamingResource:StreamingURLResource = null;
      
                public function MyPlayer()
                {
                     var factory:DefaultMediaFactory = new DefaultMediaFactory();
                     streamingResource = new StreamingURLResource(protectedMP4);
                     var mediaElement:MediaElement = factory.createMediaElement(streamingResource);
      
                     player = new MediaPlayerSprite();
                     addChild(player);
                     player.mediaPlayer.addEventListener(DRMEvent.DRM_STATE_CHANGE, this.onDRMStateChange);
      
                     player.mediaPlayer.autoPlay = true;
                     player.mediaPlayer.media = mediaElement;
                }
      
                protected function onDRMStateChange(event : DRMEvent) : void
                {
                      trace('onDRMStateChange ' + event.drmState);
                      if (event.drmState == DRMState.AUTHENTICATING)
                      {
                          //player.mediaPlayer.authenticateWithToken("token");
                          var drmTrait:DRMTrait = player.mediaPlayer.media.getTrait(MediaTraitType.DRM) as DRMTrait;
                          drmTrait.authenticateWithToken("token");
                      }
                }
      
           }
      }
      

       

      This code is heavily based on code found in another forum thread about custom token and OSMF

       

      the problem is that we don t really know when to use authenticateWithToken() if we call it on the DRMState.AUTHENTICATING event it will loop and stack overflow because calling authenticateWithToken will trigger the AUTHENTICATING event so it will loop until it will stack overflow.

       

      I also tried to call it in AUTHENCATION_NEEDED (i had to modify to server code to return this event) but then custom Token is never recieved by the server.

       

      For completness here is the part of the server code where i'd like to retrieve the raw authentication token, this code is heavily based on the reference implementation

       

      
      LicenseHandler licenseHandler = null;
      
      
      try {
      
      
      ServletInputStream in = request.getInputStream();
      
      
      ServletOutputStream out = response.getOutputStream();
      
      
      HandlerConfiguration context = getHandlerContext();
      
      
      ServerCredential licenseServerCred = getLicenseParams().getLicenseServerCred();
      
      
      licenseHandler = new LicenseHandler(context, in, out, licenseServerCred);
      
      
      licenseHandler.parseRequest();
      
      
      List<? extends LicenseRequestMessage> requests = licenseHandler.getRequests();
      
      
      // Multiple request in one message is not supported in FAXS 2.0 client.                                                                                                                                                                                                                                                                                                                                                  
      
      
      
      
      for (LicenseRequestMessage licenseReq : requests)
      
      
      {
      
      
      try {
      
      
      if (licenseReq.getRawAuthenticationToken() != null)
      
      
      {
      
      
      LOG.info("We have a auth token");
      
      
      LOG.info(licenseReq.getAuthenticationToken());
      
      
      }
      
      
      else
      
      
      {
      
      
      LOG.info("No auth token :(");
      
      
      licenseReq.setErrorData(AdobeErrorData.LACQ_AUTHENTICATION_REQUIRED);
      
      
      }
      
      
      
      
      V2ContentMetaData metadata = licenseReq.getContentInfo().getContentMetadata();
      
      
      ApplicationProperties applicationProperties = null;
      
      
      String usageModelString = null;
      
      
      if (metadata != null)
      
      
      {
      
      
      applicationProperties = metadata.getCustomProperties();
      
      
      if (applicationProperties != null)
      
      
      {
      
      
      //usageModelString = applicationProperties.getSingleValueAsUTF8String(DEMOMODE);                                                                                                                                                                                                                                                                                                                         
      
      
      
      
      }
      
      
      }
      
      
      License license = null;
      
      
      license = generateLicense(licenseReq);
      
      
      
      
      // If desired, modify the expiration or rights in the license                                                                                                                                                                                                                                                                                                                                                    
      
      
      
      
      if (license != null)
      
      
      {
      
      
      logLicenseInformation(license);
      
      
      } else {
      
      
      // No license and no error set.                                                                                                                                                                                                                                                                                                                                                                              
      
      
      
      
      LOG.error("Unknown error while generating license");
      
      
      licenseReq.setErrorData(AdobeErrorData.SERVER_ERROR);
      
      
      }
      
      
      

       

       

      licenseReq.getRawAuthenticationToken() always return null, and i checked in the log that this is the good policy that we recieve as the policy id is the same.

       

      What are we doing wrong?

       

      Thanx

        • 1. Re: Problem with custom Authentication Token
          Shan Shan Xia

          DRMState.AUTHENCATION_NEEDED or DRMState.AUTHENTICATION_ERROR is irrelevent to auth token. I suspect that OSMF client does not send out correct token request to license server.

           

          To debug it further, in drmTrait.authenticateWithToken("token"), can you try to  add a logic casting Object to ByteArray for "token"?

           

          Or else, please try to use sample video player implemented by Action Script SDK rather than OSMF.

          • 2. Re: Problem with custom Authentication Token
            _sebest_ Community Member

            To make a followup, the issue was in OSMF itself, a flash access engineer sent me a patched version of OSMF with a new event (INITIALIZED) to send the token.

             

            Here is answer:

            I have gone through the problem description as mentioned in the adobe forum. I think we have seen this issue before and according to the engineering this seems to be limitation of the current design of DRM workflows in the OSMF.

            The AUTHENTICATION_NEEDED event is dispatched when the underlying FAXS library ask for authentication information – which usually can be too late.

            The AUTHENTICATING means that the FAXS request were already made.


            If the scenario is "the token is known beforehand through external means and you just want to provide it at the start before the DRM tries to authenticate", then we have a workaround until the proper modification will be made to OSMF DRM-related workflows.

            The basic idea is:

            •       monitor when DRMTrait is added and change its delayLoadVoucher property to true (a new property)

            •       Once the DMRContentData has been set inside the DRMTrait, it will dispatch a new state : INITIALIZED

            •       On this state – you can use authenticateWithToken or authenticate to start the protected content workflow

            • 3. Re: Problem with custom Authentication Token
              n53mat Community Member

              Hi,

               

              I'm wondering if you could contact me with regards the patched version of OSMF you have with the 'delayLoadVoucher' property? I'm having similar issues with OSMF, DRM and custom token authentication.

               

              The authentication request seems to be sent automatically without my authentication code being called and with the DRMTrait, if I listen for the

              DRMState.AUTHENTICATING event the actual event never gets triggered and therefore I cannot seem to authenticate the content.

              • 4. Re: Problem with custom Authentication Token
                _sebest_ Community Member

                Hello,

                 

                here is the modified osmf.swc: http://dl.dropbox.com/u/122164/osmf.swc

                 

                there is a new DRM state: INITIALIZED

                 

                so you can now do send you Token when if (event.drmState == DRMState.INITIALIZED)

                • 5. Re: Problem with custom Authentication Token
                  n53mat Community Member

                  Couly you tell me the version of OSMF it should report?

                   

                  I can set the delayLoadVoucher no problem however the INITIALIZED event never occurs.

                   

                  Do you have a contact at Adobe that you might be ablel to provide me with?

                   

                  Thanks,

                  Mat

                  • 6. Re: Problem with custom Authentication Token
                    _sebest_ Community Member

                    I don't know the exact version as this code is not yet available in official OSMF.

                     

                    We have a support contract with Adobe, so i can't provide you a contact.

                    • 7. Re: Problem with custom Authentication Token
                      Stephen D. [Adobe] Adobe Employee

                      n53mat:   If you're still having a problem, I will ask our team internally if there is some resolution to the OSMF problem.   

                       

                      They may be aware of it.

                       

                      Regards,


                      Stephen

                      • 8. Re: Problem with custom Authentication Token
                        Stephen D. [Adobe] Adobe Employee

                        The OSMF team has some suggestions and an example of the INITIALIZED state for debug.

                         

                        Will send it to you via email.

                         

                        Regards,

                         

                        Stephen

                        • 9. Re: Problem with custom Authentication Token
                          007Eric

                          Stephen,

                           

                          Is it possible to get the OSMF example emailed to me? Also which version of OSMF is the initialized event supposedf to be added to. I have 2.0.2494 and I don't see INITIALIZED  in the DRMState.as file. Is there a way to tell from the SWC which verison it is? Can I add a listener to see when the DRMTrait is loaded?

                          • 10. Re: Problem with custom Authentication Token
                            Warfen

                            We attempted to use this fixed OSMF and using this process

                             

                            If the scenario is "the token is known beforehand through external means and you just want to provide it at the start before the DRM tries to authenticate", then we have a workaround until the proper modification will be made to OSMF DRM-related workflows.

                            The basic idea is:

                            •       monitor when DRMTrait is added and change its delayLoadVoucher property to true (a new property)

                            •       Once the DMRContentData has been set inside the DRMTrait, it will dispatch a new state : INITIALIZED

                            •       On this state – you can use authenticateWithToken or authenticate to start the protected content workflow

                             

                             

                            Unfortunatly it did not work. You never get an opertunity to call drmTrait.authenticateWithToken(); 

                             

                            I'll do a post with a solution we got working with Katherine and Eric's help

                            • 11. Re: Problem with custom Authentication Token
                              Warfen Community Member

                              Since the name of the content lets call it Video1.f4v always has a metadata file on the server called Video1.f4v.metadata we do the following.

                               

                              Step 1. Create a urlloader and load the meta data file.

                              Step 2. Call DRMManager.getDRMManager().setAuthenticationToken.

                              Step 3. Play the content

                               

                              Here is some example source code. Please note you will require to set up the server side and by on a machine

                               

                              package

                              {

                                  import flash.display.MovieClip;

                                  import flash.events.Event;

                                  import flash.net.URLLoader;

                                  import flash.net.URLLoaderDataFormat;

                                  import flash.net.URLRequest;

                                  import flash.net.drm.DRMContentData;

                                  import flash.net.drm.DRMManager;

                                  import flash.system.Capabilities;

                                  import flash.utils.ByteArray;

                                  import org.osmf.containers.MediaContainer;

                                  import org.osmf.elements.VideoElement;

                                  import org.osmf.media.MediaPlayer;

                                  import org.osmf.media.URLResource;

                                  import org.osmf.net.NetLoader;

                               

                               

                                  //Sets the size of the SWF

                                  [SWF(width="800", height="600")]

                               

                                  public class PluginTest2 extends MovieClip

                                  {

                               

                                      ////////////////////////////////////////////////////

                                      //DECLARATIONS

                                      ////////////////////////////////////////////////////

                                      public var urlLoader:URLLoader = new URLLoader();

                                      // Media Objects

                                      public var player:MediaPlayer;

                                      public var container:MediaContainer;

                                      // Customer datapacker class

                                      public var currentVideo:String = new String();

                                      public var currentVideoMetadata:String = new String();

                               

                                      ////////////////////////////////////////////////////

                                      //CONSTRUCTOR

                                      ////////////////////////////////////////////////////

                               

                                      public function PluginTest2()

                                      {

                                          trace("DRMManager supported " + DRMManager.isSupported);

                                          trace("FlashPlayer Version " + Capabilities.version );

                               

                                          if ( DRMManager.isSupported == true ) {

                                             initPlayer();

                                          }

                                      }

                               

                                      ////////////////////////////////////////////////////

                                      // Set up and init a URL request

                                      ////////////////////////////////////////////////////

                               

                                      public function initPlayer():void

                                      {

                                          currentVideo = "http://192.168.0.51:8080/content/lq2.f4v"

                                          currentVideoMetadata = "http://192.168.0.51:8080/content/lq2.f4v.metadata"

                                          urlLoader.dataFormat = URLLoaderDataFormat.BINARY;

                                          urlLoader.addEventListener(Event.COMPLETE,onUrlLoaded);

                                          urlLoader.load(new URLRequest(currentVideoMetadata));   

                                      }

                               

                                      private function onUrlLoaded(evt:Event ):void {

                                          var strAuthToken:String = new String("A Valid Token");

                                          var authToken:ByteArray = new ByteArray();

                                          authToken.writeObject(strAuthToken);

                                          var drmContentData:DRMContentData = new DRMContentData(urlLoader.data);

                                          DRMManager.getDRMManager().setAuthenticationToken(drmContentData.serverURL,drmContentData .domain,authToken);

                                          playContent();

                                      }

                               

                                      private function playContent():void{

                                          var resource:URLResource = null;

                                          resource = new URLResource( currentVideo );

                                          resource.mimeType = "video/mp4";

                                           var netLoader:NetLoader = new NetLoader();

                                           var element:VideoElement = new VideoElement( resource, netLoader );

                                          player = new MediaPlayer( element );

                                           container = new MediaContainer();

                                          container.addMediaElement( element );

                                          container.width = 300;

                                          container.height = 200;

                                          //Adds the container to the stage

                                          this.addChild(container);

                                      }

                               

                                  }

                              }

                              • 12. Re: Problem with custom Authentication Token
                                jimkoning

                                Hi Stephen,

                                 

                                Can you email the example to me too?

                                 

                                Thx,

                                • 13. Re: Problem with custom Authentication Token
                                  eoinlandyc4

                                  Can I also get a copy of this OSMF version which has the DRMState.INITIALIZED available

                                   

                                  Many thanks

                                  • 14. Re: Problem with custom Authentication Token
                                    Stephen D. [Adobe] Adobe Employee

                                    Jim and Eoin,

                                     

                                    You should receive this patch soon via your account contacts.

                                     

                                    The team is deciding about how to best publish this patch, since several have asked for it.

                                     

                                    Regards,

                                     

                                    Stephen

                                    • 15. Re: Problem with custom Authentication Token
                                      abeymg Community Member

                                      I'd also like to request a copy of the lastest OSMF version (swc+source if possible).

                                      We are AAXS customers, but not sure who our account contact is.

                                       

                                      Thanks,

                                      - Abey

                                       

                                      Abey George

                                      • 16. Re: Problem with custom Authentication Token
                                        adamjhickey Community Member

                                        Could I also be added to the list to receive this patch?

                                         

                                        Thank you.

                                        • 17. Re: Problem with custom Authentication Token
                                          marknz

                                          Has there been an update to this?

                                           

                                          Yes could you also add me to the list.