Viewer Authentication API

Introduction

Viewer Authentication API lets you implement custom authentication for authenticating viewers of live and recorded videos served by IBM Cloud Video.

You need the following before you start implementing viewer authentication:

  • Channel, which you can create on the Your channels page of your IBM Cloud Video dashboard
  • Client id, which you can obtain on the API/SDK access page of your IBM Cloud Video dashboard
  • Token, which you can obtain through the IBM Cloud Video authorization endpoint
  • Secret key, a string that will be used to create the hash in the authentication response your service passes to the IBM Cloud Video player. This secret key needs to be provided by you.

Viewer authentication flow

To implement the viewer authentication flow you need to create an application that includes the following:

  • Screens your viewers need to go through to authenticate
  • Backend code that validates these authentication requests
  • Process to pass the authentication response to the IBM Cloud Video player
Viewer authentication API flowchart Viewer authentication API example flow
  1. When the viewer clicks the log in button in the IBM Cloud Video player the entry point of your custom authentication flow is displayed in an iframe in the player.
  2. When the authentication is completed your service passes an authentication response to the player.
  3. If the authentication was successful, the player passes the authentication response to IBM Cloud Video infrastructure in a validation request.
  4. The IBM Cloud Video infrastructure validates the authentication response received from your service and passes a validation response to the player. If the response is positive, the viewer can start watching the video.

Setting up viewer authentication

Channel level

PUT https://api.ustream.tv/channels/CHANNEL_ID/locks/hash/advanced.FORMAT (format can be json or xml)
Parameters
parameter type importance Description
url string REQUIRED URL of the authentication flow entry point
secret string REQUIRED Secret key
Response

HTTP response codes returned when the action is successful:

HTTP response code Description
201 Created Viewer authentication has been set up on the channel with the new hash.
204 No Content Viewer authentication has been set up on the channel by updating the existing hash with the new one.

Specific error codes returned when the action failed:

error value HTTP response code Description
invalid_request 400 Bad Request One or more required parameters are missing (secret, url).
invalid_type 400 Bad Request The URL is invalid.
lack_of_ownership 403 Forbidden The api user is not allowed to manage the given channel
not_found 404 Not found Channel not found

Video level

By default videos inherit the authentication settings from channels but it can be overridden on a video by video basis.

Set up viewer authentication for a video

PUT https://api.ustream.tv/videos/VIDEO_ID/locks/hash.json
Parameters
parameter type importance Description
url string REQUIRED URL of the authentication flow entry point
secret string REQUIRED Secret key
Response

HTTP response code returned when the action is successful:

HTTP response code Description
204 No content Viewer authentication has been set up on the video

Implementing the authentication response

If the authentication was successful your service has to pass an authentication response to the player. The authentication response must be a JSON encoded array which contains the following:

  • list of parameters that have been hashed
  • the MD5 hash of the string that has been created by concatenating the parameters and the shared secret key with pipe "|" characters

Example script in PHP for creating the authentication response when the authentication was successful


// We create the array of parameters.
// The parameters can be anything.
$userData = [
    "username" => $_GET["user"],
    "someString" => "someValue"
];

// We create the hash by hashing
// the parameters array contents and
// the secret key
// concatenated together with a pipe character.
$hash = md5(implode('|', $userData) . '|' . $SHARED_SECRET_KEY);

// We put the array of parameters and the hash into the response.
$response = array_chunk(
    array_merge($userData, ["hash" => $hash]),
    1,
    true
);

// We encode the response into JSON format.
$json = json_encode($response);
        
The order of the parameters should match their order in the array when creating the hash.

To pass the response to the player your service has to redirect the page to the IBM Cloud Video return URL with passing the response in JSON format as a get parameter. You can test the API response at the Hash Authentication Test page.

https://www.ustream.tv/embed/hashlock/pass?hash=RESPONSE_IN_JSON_FORMAT

If the authentication failed your service has to pass a "false" string as the authentication response to the player.

https://www.ustream.tv/embed/hashlock/pass?hash=false

Managing viewer authentication settings

Channel

Getting channel viewer authentication settings

GET https://api.ustream.tv/channels/CHANNEL_ID/locks/hash.FORMAT (format can be json or xml)
Parameters

This request has no parameters.

Response

On success, key-value pairs are returned under a "hashlock" key.

Example:


{
    "hashlock": {
        "type": "advanced",
        "url": "https://align.ustream.tv/auth/123",
        "message": null,
        "button_caption": null,
        "popup_width": "0",
        "popup_height": "0"
    }
}
        

Specific error codes returned when the action failed:

error value HTTP response code Description
lack_of_ownership 403 Forbidden The api user is not allowed to manage the given channel
not_found 404 Not found Channel not found

Removing channel viewer authentication

DELETE https://api.ustream.tv/channels/CHANNEL_ID/locks/hash.FORMAT (format can be json or xml)
Parameters

This request has no parameters.

Response

On success the 200 OK HTTP response code is returned.

Specific error codes returned when the action failed:

error value HTTP response code Description
lack_of_ownership 403 Forbidden The api user is not allowed to manage the given channel
not_found 404 Not found Channel not found

Video

Getting video viewer authentication settings

GET https://api.ustream.tv/videos/VIDEO_ID/locks/hash.json
Parameters

This request has no parameters.

Response

On success, key-value pairs are returned under a "hashlock" key.

Example:

{
    "hashlock": {
        "url": "https://auth.yourdomain.com/video-authentication",
        "secret": "TOP_SECRET_KEY"
    }
}
        

Specific error codes returned when the action failed:

error value HTTP response code Description
lack_of_ownership 403 Forbidden The api user is not allowed to manage the given channel
not_found 404 Not found Video or specific authentication settings not found

Removing specific video viewer authentication settings

If you remove specific settings then video will inherit the authentication settings from the channel.

DELETE https://api.ustream.tv/videos/VIDEO_ID/locks/hash.json
Parameters

This request has no parameters.

Response

On success the 204 No Content HTTP response code is returned.

Specific error codes returned when the action failed:

error value HTTP response code Description
lack_of_ownership 403 Forbidden The api user is not allowed to manage the given channel
not_found 404 Not found Video or specific authentication settings not found

Hash lifetime and expiration

Once is successfully validated by IBM Cloud Video, the player will store the hash in the end user’s browser. This lets the viewer watch the video when returning to the page without having authenticate again.

You can specify an expiration date for the hash. When the viewer returns to the page after the expiration date, she has to authenticate again.

Expiration date has to be

  • Specified in UNIX timestamp format
  • Part of the hash by concatenating it to the rest of the parameters
  • Included in the response object as “hashExpire”.
  • JSON encoded as part of the response

Example script in PHP for specifying hash expiration date


// We specify an expiration date as a UNIX timestamp
// which is valid for one hour.
$expiration = time()+3600;

// We concatenate it to the rest of the parameters when creating the hash.
$hash = md5(implode('|', $userData).'|'.$expiration.'|'.$SHARED_SECRET_KEY);

// We include it in the response.
$response = array_chunk(
    array_merge($userData, ["hashExpire" => $expiration, "hash" => $hash]),
    1,
    true
);

// We encode the output into JSON format.
$json = json_encode($response);
        

When validating the authentication response the IBM Cloud Video infrastructure checks

  • If the expiration is a past date
  • If the expiration was hashed properly

This way we can make sure that the expiration date comes from you and it has not been tampered on the client side.

Using viewer authentication with other services

Besides the player there are some services (such as Chat, Q&A and Combined Embed) that may also require viewer authentication. In order to make the authentication work, additional steps need to be taken at the end of the authentication flow.

These services provide an url, that has to be used instead of the default pass url. This url is sent in the hashConsumer query parameter by the service to the application.

Example url in the hashConsumer in case of Chat:

https://www.ustream.tv/chat/authorize/12345678?resource=%2Fchat%2F12345678

Example script in native PHP that can authenticate the player and the services as well



// Given a json token has already been constructed
$json = json_encode($response);

// Default hash consumer for the player
$hashConsumer = 'http://www.ustream.tv/embed/hashlock/pass';
$query = [];

// Check if there is a special hash consumer
if (!empty($_GET['hashConsumer'])) {
    $hashConsumer = $_GET['hashConsumer'];

    // It's recommended to use a better URL parsing
    // technique (like PSR-7 implementations)
    $parts = parse_url($hashConsumer);

    if (!empty($parts['query'])) {
        parse_str($parts['query'], $query);
    }

    // Instead of concatenating url parts it's recommended to use
    // a better URL parsing technique (like PSR-7 implementations)
    $hashConsumer = $parts['scheme'].'://'.$parts['host'].$parts['path'];
}

$query['hash'] = $json;

$hashConsumer = $hashConsumer.'?'.http_build_query($query);

header('Location: '.$hashConsumer);