The red5pro-simple-auth-plugin
is a simple authentication plugin for Red5 Pro which enables you to add simple connection level authentication
for RTMP, RTSP and WebRTC clients. It can be configured to attach security to a webapp on-demand by adding a security configuration to the context file (red5-web.xml) of the webapp or by applying security to each web application deployed on the server.
The default security configuration of the plugin authenticates connection parameters against a simple .properties
file which contains username-password as property-value records. When the plugin is configured to apply security automatically to each webapp, it uses the simple-auth-plugin.credentials
file located at RED5_HOME/conf
directory. Custom security configuration at application-level allows you to override this for each application.
The plugin also allows fine tuning of security for each connection type (RTMP / RTSP / RTC) individually.
The plugin configuration is handled in the RED5_HOME/conf/simple-auth-plugin.properties
file. The default settings for this file are as follows:
# Simple-auth Plugin Properties
#
# Default state of server wide security
simpleauth.default.active=false
# Default data source filename [ Default authentication validator is file based ]
simpleauth.default.defaultAuthValidatorDataSource=simple-auth-plugin.credentials
# Default state of rtmp security offered by the plugin
simpleauth.default.rtmp=true
# Default state of rtsp security offered by the plugin
simpleauth.default.rtsp=true
# Default state of rtc security offered by the plugin
simpleauth.default.rtc=true
# Global state of rtmp security allowing authentication via query parameters
simpleauth.default.rtmp.queryparams=true
# Allowed rtmp agents
simpleauth.default.rtmp.agents=*
Property | Type | Description | Default value | |
---|---|---|---|---|
simpleauth.default.active | Boolean | Defines whether the plugin applies security to all applications by default or not. | false | |
simpleauth.default.defaultAuthValidatorDataSource | String | Defines the name of the default properties file (in RED5-HOME/conf) used for authentication | simple-auth-plugin.credentials | |
simpleauth.default.rtmp | Boolean | Defines the state of rtmp security when security is applies to all applications by default | true | |
simpleauth.default.rtsp | Boolean | Defines the state of rtsp security when security is applies to all applications by default | true | |
simpleauth.default.rtc | Boolean | Defines the state of rtc security when security is applies to all applications by default | true | |
simpleauth.default.rtmp.queryparams | Boolean | Defines whether rtmp authentication parameters can be provided in query string or not | true |
simpleauth.default.rtmp.agents | String | Describes the list of rtmp client types (agents) allowed to connect. This value is extracted from the rtmp client's handshake. By default all client types are allowed. It can be used to block certain types of rtmp clients from connecting. The list can be a semicolon separated list of agent strings or | | |
The RTMP agent string is obtained by Red5 Pro during handshake with the RTMP client. Each specific type of RTMP client provides an agent string to identify its type. This parameter is popularly addressed as the flashVer string. There are various types of RTMP clients such as flash player for Windows / Mac / Linux, Adobe Flash Media Live Encoder (FMLE), WireCast encoder, etc. Each client type can be identified by the value provided in the flashVer string. For more information see: Real-Time Messaging Protocol
The auth module is designed to look for the client's flashVer in the list of permissible agent strings specified. * defines that all agent types are allowed. The check does not look for an exact match, but rather whether the flashVer is contained in any one of the agent strings.
The plugin does not apply security to web applications by default. To attach the security module to a particular Red5 Pro application, you need to add a security configuration java bean in its context file - red5-web.xml
.
Example 1: Attaching plugin security to an application
To apply security to the live application, you can add the security configuration to RED5_HOME/webapps/live/WEB-INF/red5-web.xml
as shown below :
<bean id="simpleAuthSecurity" class="com.red5pro.server.plugin.simpleauth.Configuration" >
<property name="active" value="true" />
<property name="rtmp" value="true" />
<property name="rtsp" value="true" />
<property name="rtc" value="true" />
<property name="rtmpAllowQueryParamsEnabled" value="true" />
<property name="allowedRtmpAgents" value="*" />
</bean>
The name of the bean must be simpleAuthSecurity
, and it must instantiate the simple auth module configuration class - com.red5pro.server.plugin.simpleauth.Configuration
.
With the preceding configuration applied, the application requests the plugin to force authentication on RTMP
, RTSP
and WebRTC
connections. Also the application specifies the plugin will allow query string authentication for RTMP clients.
Example 2: Specifying a custom properties file
To specify a custom properties file for authentication for an application, you can use the following configuration:
<bean id="authDataValidator" class="com.red5pro.server.plugin.simpleauth.datasource.impl.Red5ProFileAuthenticationValidator" init-method="initialize">
<property name="context" ref="web.context" />
<property name="dataSource" value="/WEB-INF/simple-auth-plugin.credentials" />
</bean>
<bean id="simpleAuthSecurity" class="com.red5pro.server.plugin.simpleauth.Configuration" >
<property name="active" value="true" />
<property name="rtmp" value="true" />
<property name="rtsp" value="true" />
<property name="rtc" value="true" />
<property name="rtmpAllowQueryParamsEnabled" value="true" />
<property name="allowedRtmpAgents" value="*" />
<property name="validator" ref="authDataValidator" />
</bean>
In the above configuration we instantiate the Red5ProFileAuthenticationValidator
class with the context and relative path to the properties file. In this case, the authenticaton provider will use your validator instead of the default one and validate credentials against the information stored in your application's WEB-INF/simple-auth-plugin.credentials
.
You can copy the file
simple-auth-plugin.credentials
fromRED5_HOME/conf
directory to your webapp'sWEB-INF
dirctory.
NOTE: if any application-level property is missing in your configuration bean definition, the value for that property is copied over from the master configuration (plugin configuration).
The following parameters are allowed in a bean configuration at application level (configured in application's red5-web.xml).
Property | Type | Description | |
---|---|---|---|
active | Boolean | Sets the state of security for the application | |
rtmp | Boolean | Sets the state of RTMP security for the application | |
rtsp | Boolean | Sets the state of RTSP security for the application | |
rtc | Boolean | Sets the state of WebRTC security for the application | |
rtmpAllowQueryParamsEnabled | Boolean | Sets the state of query string-based authentication for RTMP clients | |
allowedRtmpAgents | String | Sets the list of allowed RTMP agent strings separated by semicolons. By default all agent strings are allowed. |
The authentication module stores its credentials in the RED5_HOME/conf/simple-auth-plugin.credentials
file. Each credential is stored as a property-value pair and all the credentials are loaded into memory when the server starts. If your scope configuration overrides this to use a different credentials file, the process to edit credentials would be the same as shown below.
A credential (username & password) pair is stored in a new line with a single space separating the username and the password.
Sample simple-auth-plugin.credentials file
#Simple auth credentials file
#[ Add username and password as key-value pair separated by a space (one per line) ]
#Example: testuser testpass
testuser testpass
Add a new entry by adding the new credentials in a new line.
#Simple auth credentials file
#[ Add username and password as key-value pair separated by a space (one per line) ]
#Example: testuser testpass
testuser testpass
newuser newpass
Remove credentials by removing the line.
#Simple auth credentials file
#[ Add username and password as key-value pair separated by a space (one per line) ]
#Example: testuser testpass
newuser newpass
NOTE: Red5pro server must be restarted for changes to take effect.
RTMP, RTSP and WebRTC clients must provide connection parameters when attempting to establish a connection with the server. The plugin will extract two parameters (username and password) and try to match them against the username-password pairs in the properties file.
Following are some snippets, explaining how authentication can achieved for different client types.
RTMP clients must pass authentication parameters (username & password) using the connection arguments in NetConnection.connect)
Example A
var nc:NetConnection = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
nc.connect("rtmp://localhost/myapp", "testuser", "testpass");
function onStatus(ns:NetStatusEvent):void
{
trace(ns.info.code);
}
Username and password should be the first two parameters in the arguments array being sent to Red5 Pro.
With the simpleauth.default.rtmp.queryparams=true
in the plugin configuration file or using the rtmpAllowQueryParamsEnabled
property of configuration bean set to true
, RTMP clients can also pass parameters in the query string.
Example B
var nc:NetConnection = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
nc.connect("rtmp://localhost/myapp?username=testuser&password=testpass");
function onStatus(ns:NetStatusEvent):void
{
trace(ns.info.code);
}
RTSP clients (Android & iOS) must pass authentication parameters (username & password) using the R5Configuration
object in the SDK.
Android Example
R5Configuration documented in Android SDK API
R5Configuration config = new R5Configuration(R5StreamProtocol.RTSP,
TestContent.GetPropertyString("host"),
TestContent.GetPropertyInt("port"),
TestContent.GetPropertyString("context"),
TestContent.GetPropertyFloat("buffer_time"));
config.setParameters("username=testuser;password=testpass;");
R5Connection connection = new R5Connection(config);
iOS Example
R5Configuration documented in iOS SDK API
Swift
func getConfig()->R5Configuration{
// Set up the configuration
let config = R5Configuration()
config.host = Testbed.getParameter("host") as! String
config.port = Int32(Testbed.getParameter("port") as! Int)
config.contextName = Testbed.getParameter("context") as! String
config.parameters = @"username=testuser;password=testpass;";
config.`protocol` = 1;
config.buffer_time = Testbed.getParameter("buffer_time") as! Float
return config
}
WebRTC clients (Using Red5 Pro HTML5 SDK) must pass authentication parameters using the connectionParams
property of the baseConfiguration
object.
Example:
var baseConfiguration = {
host: window.targetHost,
app: 'myapp',
iceServers: iceServers,
bandwidth: desiredBandwidth,
connectionParams: {username: "testuser", password: "testpass"}
};
To get this plugin to work properly with your application it is important to follow the application lifecycle. The plugin intercepts the invocation of the method - public boolean appConnect(IConnection conn, Object[] params)
. Hence it is important that your application's main class (MultithreadedApplicationAdapter) calls the super method properly.
Your application class must make a call to the super method as shown in the snippet.
@Override
public boolean appConnect(IConnection conn, Object[] params){
// your custom logic here
// your custom logic here
return super.appConnect(conn, params);
}
Returning a
true
orfalse
directly will make your application get out of the plugin's call chain.
STEP 1
If you wish to get more out of this plugin such as authenticating against different sources etc, you can implement your own validator class by implementing the IAuthenticationValidator
interface.
Example :
public class CustomSourceValidator implements IAuthenticationValidator {
private static Logger logger = Red5LoggerFactory.getLogger(CustomSourceValidator.class, "CustomSourceValidator");
private Object dataSource;
public CustomSourceValidator()
{
}
public CustomSourceValidator(Object dataSource)
{
this.dataSource = dataSource;
}
@Override
public void initialize()
{
// load / initialize your data source object here
}
@Override
public boolean onConnectAuthenticate(String username, String password, Object[] rest)
{
try
{
// authenticate here and return a true if authentication is successful, else return false
}
catch(Exception e)
{
logger.error("Error validating credentials : " + e.getMessage());
return false;
}
}
public Object getDataSource() {
return dataSource;
}
public void setDataSource(Object dataSource) {
this.dataSource = dataSource;
}
}
Clustering involves a group of interconnected nodes (origins and edges). A publisher stream is streamed from an origin to one or more edges by the Red5 pro restreamer
. In the context of a Red5 pro ecosystem ,the restreamer itself is a connection. Hence when the simple auth plugin is turned on, the authentication restriction applies to the restreamer
as well. The red5pro-simple-auth-plugin
treats a restreamer
connection as a special client identified by the class name com.red5pro.server.stream.util.restreamer.ConnectorShell
.
The red5pro-simple-auth-plugin
checks the connection class name for each IConnection
during authentication and allows the restreamer
connection to passthrough unconditionally.
When extending the red5pro-simple-auth-plugin
busing a IAuthenticationValidator
or implementing your own custom plugin that needs to work on a Red5 Pro cluster, make sure to check for the IConnection
classname. you can use the following sample snippet to check for a restreamer
connection.
static String RESTREAMER = "com.red5pro.server.stream.util.restreamer.ConnectorShell";
IConnection connection = Red5.getConnectionLocal(); // Or the `IConnection` could also be a passed param
String connectionClassName = connection.getClass().getCanonicalName();
if(connectionClassName.equalsIgnoreCase(RESTREAMER))
{
// This is a restreamer connection
}
If the class name represents the restreamer
, you should make sure to allow it to pass through unconditionally in your custom logic.
STEP 2
Instantiate your custom validator using spring in red5-web.xml
and pass it as a reference to the simpleAuthSecurity
configuration bean.
<bean id="authDataValidator" class="com.example.CustomSourceValidator" init-method="initialize">
<property name="dataSource" ref="{data-source-object}" />
</bean>
<bean id="simpleAuthSecurity" class="com.red5pro.server.plugin.simpleauth.Configuration" >
<property name="active" value="true" />
<property name="rtmp" value="true" />
<property name="rtsp" value="true" />
<property name="rtc" value="true" />
<property name="rtmpAllowQueryParamsEnabled" value="true" />
<property name="allowedRtmpAgents" value="*" />
<property name="validator" ref="authDataValidator" />
</bean>
The plugin will now use your custom validator to validate the authentication info.
This authentication plugin can also be used with Red5 pro clusters built manually or using streammanager.
Clustering involves a group of interconnected nodes (origins and edges). A publisher stream is streamed from an origin to one or more edges by the Red5 pro restreamer
. In the context of a Red5 pro ecosystem ,the restreamer itself is a connection. Hence when the simple auth plugin is turned on, the authentication restriction applies to the restreamer
as well. The red5pro-simple-auth-plugin
treats a restreamer
connection as a special client with the following credentials.
username : cluster-restreamer
password: <cluster-password>
The username for a restreamer
is always cluster-restreamer
and the password is the clustering password configured in the cluster configuration file cluster.xml
located at RED5_HOME/conf/cluster.xml
.
You can choose authenticate the restreamer in one of the following ways:
restreamer
credentials to your authentication data source.IAuthenticationValidator
as described earlier and have the implementation verify the restreamer
username and the cluster
password locally (on the server) without connecting to the data source.WHEN TO USE
WHEN NOT TO USE