Skip to content

Authorize playback with token

On servers accessible over the internet, it's almost immediately necessary to organize viewing protection, allowing access to those users who are permitted and revoking the viewing ability from those who are no longer allowed.

Flussonic, in addition to traditional and costly systems like DRM, offers an affordable and very effective scheme in which the portal that viewers visit issues a playback link with an enabled unique token, and the media server itself checks this token.

This setup is particularly suited for content distributed directly from a media server, and different arrangements may be needed when using a CDN or DRM.

Configure test example

Install the trial version of Flussonic, and within a few minutes, you'll be able to launch a protected stream for testing.

http 8080;
rtmp 1935;
rtsp 1554;

auth_backend play-auth {
    allow token test1;
}

stream auth-check {
    input fake://fake;
    on_play auth://play-auth;
}

How does protection works?

Different players and user devices will display in various ways that the protected video stream is no longer available for playback. For example, ffmpeg will show the following message indicating the unavailability:

$ ffmpeg  -i rtmp://localhost/rtmp/auth-check
ffmpeg version 6.1.1 Copyright (c) 2000-2023 the FFmpeg developers
...
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
[in#0 @ 0x600001c9c700] Error opening input: Input/output error
Error opening input file rtmp://localhost/rtmp/auth-check.
Error opening input files: Input/output error

ffmpeg doesn't tell the details because rtmp doesn't have standards way to tell about protection failure. HTTP protocols have more standard way:

$ curl -v http://localhost:8080/auth-check/index.m3u8 -o /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /auth-check/index.m3u8 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.1.2
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< access-control-allow-headers: x-vsaas-session, x-no-redirect, origin, authorization, accept, range, content-type, x-add-effective, session, x-originator, x-sid
< access-control-allow-methods: GET, PUT, DELETE, OPTIONS
< access-control-allow-origin: *
< access-control-expose-headers: Server, range, X-Run-Time, X-Sid, Content-Length, Location
< content-length: 1147
< date: Sat, 03 Feb 2024 19:16:16 GMT
< server: Streamer 24.02
< x-deny-reason: backend_denied
< x-route-time: 172
< x-run-time: 210
< 

403 code means that authorization declines this view.

How to play with token?

HTTP

HTTP protocols: HLS, DASH, MSS, LL-HLS, WebRTC just assume that you will add token into request query string.

$ curl http://localhost:8080/auth-check/index.m3u8?token=test1
#EXTM3U
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=260000,BANDWIDTH=320000,RESOLUTION=320x240,FRAME-RATE=25.000,CODECS="avc1.42c015,mp4a.40.2",CLOSED-CAPTIONS=NONE
tracks-v1a1/mono.m3u8?token=test1

$ ffmpeg -i http://localhost:8080/auth-check/index.m3u8?token=test1
...
[hls @ 0x11f604b70] Opening 'http://localhost:8080/auth-check/tracks-v1a1/mono.m3u8?token=test1' for reading
[hls @ 0x11f604b70] Skip ('#EXT-X-VERSION:3')
[hls @ 0x11f604b70] Skip ('#EXT-X-PROGRAM-DATE-TIME:2024-02-03T19:31:31.839Z')
[hls @ 0x11f604b70] Opening 'http://localhost:8080/auth-check/tracks-v1a1/2024/02/03/19/31/36-05000.ts?token=test1' for reading
[hls @ 0x11f604b70] Opening 'http://localhost:8080/auth-check/tracks-v1a1/2024/02/03/19/31/41-05000.ts?token=test1' for reading
Input #0, hls, from 'http://localhost:8080/auth-check/index.m3u8?token=test1':
  Duration: N/A, start: 73249.691911, bitrate: N/A
  Program 0 
    Metadata:
      variant_bitrate : 320000
  Stream #0:0: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 90k tbn
    Metadata:
      variant_bitrate : 320000
  Stream #0:1(eng): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp
    Metadata:
      variant_bitrate : 320000

RTSP

RTSP is very similar, it also has standard URL and standard way to pass query string:

$ ffmpeg -i rtsp://localhost:1554/auth-check?token=test1
...
Input #0, rtsp, from 'rtsp://localhost:1554/auth-check?token=test1':
  Metadata:
    title           : Streamer 24.02
  Duration: N/A, start: 0.003000, bitrate: N/A
  Stream #0:0: Video: h264 (Constrained Baseline), yuv420p(progressive), 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 90k tbn
  Stream #0:1(eng): Audio: aac (LC), 48000 Hz, stereo, fltp

RTMP

With RTMP, things are a bit more complicated due to the lack of a unified approach to URL handling, leading to various methods for transmitting authorization information. A common practice has emerged to append the query string to the play function parameters, combining it with the stream name, which is precisely what ffmpeg does.

$ ffmpeg -i rtmp://localhost/static/auth-check?token=test1
...
Input #0, flv, from 'rtmp://localhost/static/auth-check?token=test1':
  Metadata:
    |RtmpSampleAccess: true
    audiochannels   : 2
  Duration: 00:00:00.00, start: 0.000000, bitrate: N/A
  Stream #0:0: Data: none
  Stream #0:1: Video: h264 (Constrained Baseline), yuv420p(progressive), 320x240 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1k tbn
  Stream #0:2: Audio: aac (LC), 48000 Hz, stereo, fltp, 28 kb/s

SRT

We have separate page about SRT playback authorization.

UDP MPEG-TS

The UDP MPEG-TS protocol (multicast transmission) does not include client-server interaction, meaning the server is unaware of its streams being accessed, making this authorization method inapplicable. However, multicast does not operate over the internet, and access restriction challenges differ. For these scenarios, encryption and CAS (Conditional Access System) are utilized to secure content.

How to manage authorization tokens

Listing tokens in the configuration should never be the primary mechanism. Similar "secret" keys, created for debugging convenience and then forgotten, have been seen to leak online and become actively used.

The main mechanism for generating and checking tokens should be implemented on your portal's side (middleware, website) with a system that both generates and verifies tokens independently​​.

If you don't yet have a Flussonic subscription or a trial license, you can request a free trial key via their website. Setting up the server takes little time, and you can start with the test configuration provided at the beginning of the article. Additionally, Flussonic's technical specialists are eager to assist in finding cost-effective and efficient solutions for protecting your video content from unauthorized viewing.