Authenticating subscribers in a Red5 Pro Application

This article discusses the issue of stream security for subscribers over the various protocols supported by Red5pro (RTMP, RTSP and WebRTC) programmatically. IF you are new to the world of Red5/Red5Pro, I would suggest taking a peek at the Red5 development series on Github. Here you can find information ranging from what is Red5 to how to create and debug an application.

 

NOTE: I always use the terms Red5 and Red5pro interchangeably. So don’t be confused because Red5pro is built upon the well structured open source Red5. While Red5 open source is limitd to RTMP, Red5pro support RTSP, HLS, WebRTC and much more..

 

The most important thing to know before you start coding anything for Red5 is the Red5 application structure. A quick lesson on the Red5 Application structure is available here.

To keep this article simple to understand, I will be implementing the code in the Red5 Application Adapter (main class) itself. This kind of stuff can also be achieved via plugins. But I won’t be going into that just yet. It is just to inform you that implementing stuff through plugins is the advanced way of doing things.

HLS Security is not explicitly supported by Red5pro since it is not an internal protocol of Red5Pro core streaming engine. Security for HLS request can be built using standard client-server mechanisms. This will be discussed in a separate article.

 

Given below is a simple Red5/Red5pro application main class (also known as the application adapter):

 

import org.red5.logging.Red5LoggerFactory;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.scope.IScope;
import org.slf4j.Logger;

/**
* Sample application
*/

public class Application extends MultiThreadedApplicationAdapter {

private static Logger log = Red5LoggerFactory.getLogger(Application.class);

@Override
public boolean appStart(IScope arg0)
{
return super.appStart(arg0);
}

@Override
public void appStop(IScope arg0)
{
super.appStop(arg0);
}

}

 

Now make your class implement the IStreamPlaybackSecurity interface. The IStreamPlaybackSecurity interface adds a security handler method to your class which can intercept stream playback calls, irrespective of the client type used for making the playback request for the stream.

@Override
public boolean isPlaybackAllowed(IScope scope, String name, int start, int length, boolean flushPlaylist)
{
return false;
}

The isPlaybackAllowed method returns a boolean value. If a false is returned a playback request is not accepted by the application. So that’s the key to building security for subscribers. This method is not invoked for publishers.


 

Now that we know where the authentication logic will go in, we need to know how to capture parameters from connecting clients and then validate them inside our isPlaybackAllowed method. A detailed lesson on capturing parameters on client ‘connect’ event has been discussed in a different article previously. You may want to check it out before we can proceed.

Assuming that you have gone through “How to capture parameters on connection”, we shall now look at a sample pseudo-logic which check the parameters to see if a user has subscribe permissions or not. If yes we return true otherwise we return false.

import org.red5.logging.Red5LoggerFactory;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.stream.IStreamPlaybackSecurity;
import org.red5.server.api.IConnection;
import org.red5.server.api.scope.IScope;
import org.slf4j.Logger;

/**
* Sample application
*/

public class Application extends MultiThreadedApplicationAdapter implements IStreamPlaybackSecurity {

private static Logger log = Red5LoggerFactory.getLogger(Application.class);

@Override
public boolean appStart(IScope arg0)
{
return super.appStart(arg0);
}

@Override
public void appStop(IScope arg0)
{
super.appStop(arg0);
}

@Override
public boolean isPlaybackAllowed(IScope scope, String name, int start, int length, boolean flushPlaylist)
{
IConnection connection = Red5.getConnectionLocal();
Map<string, object=""> map = getParameters(connection.getConnectParams());</string,>

if (!map.containsKey("token"))
{
// Extract token and validate it here and return true if valid
String token = String.valueOf(map.get("token"));
return true;
}

return false;
}

}

The ‘isPlaybackAllowed’ method provides us with the following parameters:

IScope scope: The logical application space where the stream is being requested from. A scope can be the application itself or a logical sub-space inside the application.

String name: The stream name being requested for playback.

int start: NA

int length: NA

int flushPlaylist: NA


In the above pseudo logic, we capture the parameters map irrespective of the protocol used into a HashMap – ‘map’. We expect a secret token value to be supplied via key ‘token’ by the client. This token can then be validated against a stored value. If the token value is correct we return true else we return false.

While the above pseudo logic is just an example, you could be having multiple parameters being sent in from the client side, which you may want to use in your validation.

The ‘token’ is passed to the application as a connection parameter via query string for RTMP, via Android/IOS SDK for RTSP and via HTML5 SDK for WebRTC clients in Red5pro. [ Passing and capturing connection parameters is discussed ina different article ]

If you have trouble getting emails from this domain, please check your email spam & mark messages from flashvisions.com as 'Not Spam'

Comments are closed