Goal
Create an authorization scheme for streaming servers that can be used to secure access to streaming media.
Strategy
Append a dynamic stream token to the end of the media URL that is passed to the media server. The media server then passes the token back to Avalon, which confirms or denies the validity of the request.
Token generation
A random token is generated when a user requests a media view page on Avalon. This token, along with the media's path and an expiration date (typically 20 minutes into the future) is inserted into the stream_tokens
table. One user can have many tokens.
Protocol-specific Implementations
HTTP Live Streaming (HLS)
Given the HTTP Live Streaming Media URL:
http://streaming.example.edu/avalon/mediapackage_id/derivative_id/filename.mp4.m3u8?token=dynamic_stream_token
When a user requests the above HLS stream, the streaming server takes the token and calls Avalon at
http://avalon.example.edu/authorize.txt?token=dynamic_stream_token
Avalon looks up the token in the stream_tokens
table, if the token is valid and hasn't expired, it returns the paths to the authorized streams:
mediapackage_id/derivative_id/filename
The streaming server compares this path to the requested HLS stream, if they match it serves the m3u8 file so the user can start streaming.
Issue: The .m3u8
file is just a playlist full of .ts
"chunks." By securing the .m3u8
request, we establish some measure of security, but there's nothing preventing a user from saving the .m3u8 file and loading it again later. Securing the .ts files with tokens is possible, but may foil Apache's caching, resulting in tremendous performance degradation.
RTMP
RTMP has been deprecated since Avalon 6
Given the RTMP Media URL:
The Flash player does the following:
- Connect to the application URL
rtmp://media.example.edu/avalon?token=dynamic_stream_token
- Request the stream
mp4:mediapackage_id/derivative_id/filename.mp4
(Notice that the application URL has the query string/token appended to it, while the stream, which was between the two in the media URL, does not.)
Issue: The /avalon
application on the server-side can handle Step 1 in an onConnect()
handler, but does not provide a mechanism for handling Step 2, where the stream itself would have to be authenticated.
Solution: The onConnect()
handler can override the client's access control list before any streams are requested. The strategy, therefore, is for Adobe Media Server to pass dynamic_stream_token
back to Avalon via a REST call. Avalon responds either with a 403 Unauthorized
error, or with the mediapackage_id
that the token is valid for. By then limiting client access to /mediapackage_id/*
, the application ensures that the token can only be used to access the stream(s) it's authorized for.