How to authenticate Wowza clients via your own server remotely

"Only a life lived for others is a life worthwhile." – Albert Einstein

How to authenticate Wowza clients via your own server remotely

INTRODUCTION


The ModuleRemoteAuthentication module for Wowza Streaming Engine™ media server software can be used to implement remote authentication of client sessions. This means you need not bother about complicated things such as JDBC, database authentication, or writing complex authentication logic to interface the module with the system of your choice. Using ModuleRemoteAuthentication you just need to provide the module with a remote server endpoint that returns authentication responses in JSON format and the module will handle everything else for you.

Contents


Prerequisites


Wowza Streaming Engine 4.8.x or later is required.

Installation


  1. Download the latest release of rtmpworld-wse-plugin-remoteauthentication  & rtmpworld-wse-utilities shared library archives.
  2. Extract the contents from the downloaded (zipped) packages.
  3. Rename extracted files lib/rtmpworld-wse-plugin-remoteauthentication-x.x.x.jar to lib/rtmpworld-wse-plugin-remoteauthentication.jar & rtmpworld-wse-utilities-x.x.x.jar to rtmpworld-wse-utilities.jar
  4. Then copy the lib/rtmpworld-wse-plugin-remoteauthentication.jar & rtmpworld-wse-utilities.jar file from the package to the lib folder in your Wowza Streaming Engine installation ([install-dir]/lib).
  5. Restart Wowza Streaming Engine.

NOTE: rtmpworld-wse-utilities shared library (rtmpworld-wse-utilities.jar) is a dependency for all our modules. It is not a module in itself. It simply contains resources that are used by our modules at runtime. If you are using multiple modules from us then you should copy this file just once into the lib folder of your Wowza Streaming Engine installation ([install-dir]/lib).

Configuration


To enable this module, add the following module definition to your application configuration. See Configure modules for details.

NAMEDESCRIPTIONFULLY QUALIFIED CLASS NAME
ModuleRemoteAuthentication
Allows authentication via remote server URL over HTTP/HTTPS
com.rtmpworld.server.wowza.plugins.ModuleRemoteAuthentication

Properties


After enabling the module, you can adjust the default settings by adding the following properties to your application. See Configure properties for details.

PATHNAMETYPEVALUENOTES
/Root/ApplicationremoteauthAuthEndPoint
Stringhttp://example.com/security/auth.php
URL of the remote authentication endpoint which will handle authentication for all types of client requests except (digest authentication).

/Root/Application
remoteauthUserPassEndPoint
Stringhttp://example.com/security/userpass.phpURL of the remote authentication endpoint which will handle authentication for clients that support digest authentication with username and password only.

/Root/Application
remoteauthAuthValidator
String${com.wowza.wms.ConfigHome}/authfields.json
Absolute path to validation template JSON file. This  file provides meta information for in memory validation of fields passed in my non-digest clients.
/Root/Application
remoteauthAuthMode
Number
1 | 2 | 3
Authentication mode to use. ONCONNECT(1), ONPUBLISH(2), ONSUBSCRIBE(3).  Composite  (combinations) authentication modes are not supported.

/Root/Application
remoteauthAuthAsync
Boolean
True/False
Selects whether authentication thread should block and wait (sync) till it receives response form server  or allow client to session to proceed while waiting for response in background.

/Root/Application
remoteauthDebug
BooleanTrue/False
Toggles debug mode for the module for increased logging.
/Root/Application
remoteauthThreadPoolSizeNumber5 (default)The number of threads used to send data.
/Root/Application
remoteauthDelayForFailedRequestsNumber1000 (default)Time, in milliseconds, to wait between failed requests.
/Root/Application
remoteauthThreadPoolTerminationTimeoutNumber5 (default)When shutting down, time, in seconds, to wait to allow all requests to be sent.

Use Wowza Engine Manager interface to add & configure modules for your Wowza Streaming Engine instance.

Usage


The module allows you to authenticate client sessions with respect to different action events in a Wowza stream lifecycle. You can authenticate a client session on connect, publish, or playback (selected via AuthMode). You can write the authentication handlers in any programming language of your choice and configure the module to interface with it.

For Developers


AUTHENTICATION FOR DIGEST/BASIC AUTH SUPPORTING CLIENTS


Commonly people use two types of publishers  One with digest/basic authentication support and the other without (query-string). The encoders with digest authentication such as FMLE/OBS will capture username and password through the application UI and pass them to the Wowza authentication system via ModuleCoreSecurity. The custom username & password provider in our module will pass the username to your remote endpoint configured via remoteauthUserPassEndPoint. Your script should return the correct password back to the module for comparison and authentication. If the passwords match, the client will be allowed access or rejected.

POST PARAMETERS
NAMETYPEVALUE/SAMPLE VALUESNOTES
eventStringcheckuser, getpasswordName of the event

usernameStringUsername of the publisher

timestampNumber
1644924533Timestamp in UTC milliseconds

All parameters will be prefixed with “wow_” to keep parameters well-scoped. ie, post parameter “var” is actually “wow_var”.

Setting up the authentication system consists of two parts :

  1. Registering the module to intercept clients
  2. Authenticating clients with a remote server.
1. REGISTERING THE MODULE CLASS FOR USERNAME-PASSWORD AUTHENTICATION
  • To intercept RTMP authentication, add the following property to the <Properties> container at the bottom of [install-dir]/conf/[application]/Application.xml (be sure to add the property to the correct <Properties> container; there are several in Application.xml).
<Property> 
   <Name>securityPublishUsernamePasswordProviderClass</Name> 
   <Value>com.rtmpworld.server.wowza.plugins.ModuleRemoteUsernamePasswordProvider</Value> 
</Property>
  • RSTP authentication is not currently supported with basic/digest methods. for more information, please check out the Known Issues section.
2. AUTHENTICATING WITH A SERVER SCRIPT REMOTELY
SERVER-SCRIPT EXAMPLE(s) – userpass.php
<?php  
    $prefix = "wow_";
    $event =  $_REQUEST[$prefix."event"];
    $username =  $_REQUEST[$prefix."username"];
    $wowza_server_ip = $_SERVER['REMOTE_ADDR'];
    $response_data = NULL;


    switch ($event) {
        case "getpassword":
            // check if user exists and if yes return the password
            $response["data"] = "mypassword";
          break;
        case "checkuser":
            // check if user exists and return true/false
            $response["data"] = true;
            break;
        default:
          break;
      }
   
    $response["timestamp"] = time();
    $response_json = json_encode($response);


    // return json response
    echo $response_json;
?>

Always use HTTPS on your remote authentication server to enable transport level encryption/decryption. This way you do not need to worry about sending your password in plain text or otherwise back to the wowza module.

AUTHENTICATION FOR QUERY-STRING/PATH-PARAMS SUPPORTING CLIENTS


Client sessions that do not support digest authentication such as FFMPEG, VLC, custom RTSP and WebRTC clients etc can pass parameters via query string.  If a value for remoteauthAuthValidator is set, then the JSON schema is used to validate fields locally before posting to the remote server for authentication. If the path does not exist or is not set the data is directly posted t the remote server URL defined by remoteauthAuthEndPoint without any local validations. Data for each action event is posted alongside various client/session attributes that will help the remote server in the authentication.

POST PARAMETERS
NAMETYPEVALUE/SAMPLE VALUESNOTES
eventStringonconnect, onpublish, onsubscribeName of the event
clientipString127.0.0.1Remote IP of the client/session
forwarededipString127.0.0.1Forwarded IP of the connected client, if available.
uriStringWhen shutting down, time, in seconds, to wait to allow all requests to be sent. (default: 5)
useragentStringThe user-agent string of the client/session. For RTMP clients it will be the flashVer string
streamStringmystreamThe stream name of the stream involved in the event (applicable to stream actions).
querystringString?param=valueQuery string passed into the server by the client. Could be a play/publish name query string for a session or query string passed in during connection.
referrerStringReferrer string
appinstanceStringApplication instance name from which the request originates
userdataStringCustom data from a WebRTC application as a JSON
cookiestrStringCookie String
timestampNumber1644924533Timestamp in UTC milliseconds

All parameters will be prefixed with “wow_” to keep parameters well scoped. ie, post parameter “var” is actually “wow_var”.

SERVER-SCRIPT EXAMPLE(s) – authenticate.php
<?php

    $prefix = "wow_";  
    $event =  $_POST[$prefix."event"];
    $clientip =  $_POST[$prefix."clientip"];
    $forwardedip =  $_POST[$prefix."forwardedip"];
    $queryStr =  $_POST[$prefix."querystr"];
    $useragent = $_POST[$prefix."useragent"];
    $referrer =  $_POST[$prefix."referrer"];
    $uri =  $_POST[$prefix."uri"];
    $cookieStr=  $_POST[$prefix."cookiestr"];
    $userdata = "{}";
    $wowza_server_ip = $_SERVER['REMOTE_ADDR'];

    if(isset($_POST[$prefix."userdata"])){
        // from webrtc only
       $userdata = $_POST[$prefix."userdata"];
    }

    $is_allowed = true;


    switch ($event) {
        case "onconnect":
            // do auth here and set $is_allowed
          break;
        case "onpublish":
            // do auth here and set $is_allowed
            break;
        case "onsubscribe":
            // do auth here and set $is_allowed
            break;                
        default:
            $is_allowed = false;
          return;
      }


    $response["is_allowed"] = $is_allowed;
    $response["timestamp"] = time();
    $response_json = json_encode($response);
    echo $response_json;
?>

PASSING PARAMETERS

RTMP

RTMP clients that support query string parameters can make use of this module for normal authentication and clients (publishers mostly) that support digest authentication should use the securityPublishUsernamePasswordProviderClass implementation via ModuleCoreSecurity.

RTSP

Only RTSP player clients that support query params are entertained by the module. Digest/basic auth modes are not currenty supported.

WEBRTC

WebRTC clients can pass in custom params via UserData . The UserData is a json object comprising of attributes and values. You can add your custom param as a new attribute-value pair in it.

{ param1: 'value1' }

HLS

HLS clients will pass various information from their requesting URL including client IP, URI, query string & cookie string. The easiest way to pass parameters to the authentication endpoint would be to add them to the query string of the url.

Known Issues


  • Authentication for RTSP clients in basic & digest mode is not currently supported through this plugin. To work around this You have two options to work around this using official docs:
    • With ModuleCoreSecurity enabled, Disable RTSP authentication, and all RTSP publishers connect unconditionally
    • Rely on the built-in mechanism for basic/digest authentication in ModuleCoreSecurity via rtspEncoderAuthenticateFile.
  • Authentication for HLS clients is done through query parameters passed in via URL.