VID-12: Token Checker

Issue Information

Issue Type: New Feature
Priority: Major
Status: Closed

Reported By:
Ben Tasker
Assigned To:
Ben Tasker
Project: (VID)
Resolution: Done (2019-04-18 18:10:49)
Target version: v0.14,
Components: Authentication ,

Created: 2019-04-18 14:43:38
Time Spent Working

Need to implement a token validator which can be run in Openresty to validate that a HMAC token provided as part of the URL is valid.

The tokens are minted by the script created in VID-11 and are a SHA256 HMAC generated based upon a string comprised of the following

To be considered valid:

- The token must not have expired (i.e. os.time() >= expiry)
- The HMAC should validate (i.e. we can regenerate the same string using the secret)

Variables used to supply the token in a request (as per VID-10) are t (token) and e (expiry) in the querystring.

Once the basic functionality is in place, want to look at improving so that a token can be used for segments too (currently we can only force protection for master manifests, otherwise playback would fail). That'll likely involve using dirname on the path when minting a token, and then adjusting the validator to push the token into a cookie (or similar). That can be dealt with properly later - the prime concern currently being to ensure VID-11 tokens can be used - but should be kept in mind.

Issue Links

Toggle State Changes


OK, as a quick mock-up, this is sufficient to validate the HMAC itself
local table = table
local require = require
local string = string
local os = os
local sha256 = require "lib.sha256"

local function mint_token(path,expires,ip,secret)
    local mint = {path,expires,ip}
    local mintstr = table.concat(mint,':')
    -- print mintstr
    return sha256.hmac_sha256(secret,mintstr)

-- Use same static values as were used to mint the origin token
referer = ''
vidpath = '2019/08/16.m3u8'
ip = ''
secret = '1234abcd'
httpref = ''

-- From the token minted earlier
local provided = '830a80dfe53cf869251eecb921416b66524b43767b1673177d055cddb826a983'
local expires = 1555598449

local now = os.time()

if (os.time() > expires)
    print("Deny Time")

local nowtok = mint_token(vidpath,expires,ip,secret)

if now == provided
    print("Deny Tok")

commit eb684167417a96d3a676c814024fa253dbdc834e
Author: B Tasker <github@<Domain Hidden>>
Date: Thu Apr 18 16:08:38 2019 +0100

Commit Message: VID-12 Create token validation script.

Reads token and expiry in from the query string and checks if they're valid for the time of the request, and the path that's being requested.

Functionality currently works. However, if enforced, it would currently break playback:

* Player would correctly request a token, and include it alongside a master manifest request
* Any submanifest requests, or segment requests, would not include the token and so would be denied

The next step is to address that

resources/tokenisation/minter/token_validate.lua | 66 ++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)

View Commit | View Changes
So, in order to allow token enforcement against segments and submanifests, I think the best way is to make a few (relatively small) changes

- The VID-11 token minter should run the equivalent of dirname on vidpath so that the token is minted against the container directory
- The validator should do the same with uri
- Once a token has been successfully validated from the query string, it should be pushed to the client in a cookie
-- To avoid breaking multi-player support, the cookie name should be derived from the path (so that multiple playback urls have distinct cookie names)

The token auth won't recurse down through directories (i.e. if the token is issued for /foo/foo.m3u8 it can be used for /foo/foo.ts but not /foo/bar/foo.ts), but the only way around that would be to either walk down the tree of uri in the validator, or to use a packed rather than a hashed token.

As this will require changes to be made to both the VID-11 code and this code, I'll raise a new issue to cover the changes so that comments don't need to be duplicated between.

That'll be VID-13
btasker changed status from 'Open' to 'Resolved'
btasker added 'Done' to resolution
btasker changed status from 'Resolved' to 'Closed'