Authenticating subscribers in a Red5pro 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());

  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 ]

Authenticating publishers in a Red5pro Application

Red5pro offers exciting new ways of engaging your users online with live streams and data online. You can publish live streams and even record them using flash player (desktop), android/ios (mobile) and WebRTC (HTML5 browser).

However, stream security for publishing still lingers as a challenge for the administration. This article discusses how you can secure your publishing streams for 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.

 

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 IStreamPublishSecurity interface. The IStreamPublishSecurity interface adds a security handler method to your class which can intercept stream publish calls, irrespective of the client type used for publishing the stream.

@Override
public boolean isPublishAllowed(IScope scope, String name, String mode)
{
  return false;
}

The isPublishAllowed method returns a boolean value. If a false is returned a publish request is not accepted by the application. So there you go! that’s the key to building security for publishers. This method is not invoked for subscribers.


 

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 isPublishAllowed 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 no look at a sample pseudo-logic which check the parameters to see if a user has publishing 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.IStreamPublishSecurity;
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 IStreamPublishSecurity {

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 isPublishAllowed(IScope scope, String name, String mode)
{
  IConnection connection = Red5.getConnectionLocal();
  Map<String, Object> map = getParameters(connection.getConnectParams());

  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;
}

}

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.

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 ]

Free red5pro unofficial wallpapers

Worked on a few Red5pro wallpapers for fun this weekend (non-commercial of course). Sharing them in here. If you like them, please let me know.

 

Click the link at the end of this post to download wallpapers as zip.

 

WALLPAPER #1

 

(more…)

FLPlayer – Free OSMF based RTMP live stream player for Android

FLPlayer is a OSMF based simple application for playing flash based live video streaming content to android devices. FLPlayer works with popular streaming servers like Flash media server, Wowza media server or Red5 media server to play live video content. FLPlayer is suitable for both business to consumer redistribution and/or first hand usage.

(more…)