Daily Archives: September 17, 2015

Wowza Secure URL params Authentication for streams in an application

To secure the publishers for a common application through username -password specific for streamnames , this post is useful . It  uses Module Core Security to prompt back the user for supplying credentials.

The detailed code to check the rtmp query-string for parameters  and performs the checks –  is user is allowed to connect and is user allowed to stream on given streamname is given below .

Initialize the hashmap containing publisher clients and IapplicationInstance

	HashMap <Integer, String> publisherClients =null;
	IApplicationInstance appInstance = null;

On app start initilaize the IapplicationInstance object .

	public void onAppStart(IApplicationInstance appInstance)
	{
		this.appInstance = appInstance;
	}

Onconnect is called called when any publisher tries to connects with media server. At this event collect the username and clientId from the client.
Check if publisherclient contains the userName which client has provided else reject the connection .


	public void onConnect(IClient client, RequestFunction function, AMFDataList params)
	{

		AMFDataObj obj = params.getObject(2);
		AMFData data = obj.get("app");

		if(data.toString().contains("?")){

			 String[] paramlist = data.toString().split();
			 String[] userParam = paramlist[1].split("=");
			 String userName = userParam[1];

			if(this.publisherClients==null){
				this.publisherClients = new HashMap<Integer, String>();
			}

			if(this.publisherClients.get(client.getClientId())==null){
				this.publisherClients.put(client.getClientId(),userName);
			} else {
				client.rejectConnection();
			}
		}
	}

AMFDataItem: class for marshalling data between Wowza Pro server and Flash client.

As the event user starts to publish a stream after sucessful connection Onpublishing function is called . It extracts the stream name from the client ( function extractStreamName() )and checks if user is allowed to stream on the given streamname (function isStreamNotAllowed()) .

	public void publish(IClient client, RequestFunction function, AMFDataList params)
	{
		String streamName = extractStreamName(client, function, params);
		if (isStreamNotAllowed(client, streamName))
		{
			sendClientOnStatusError(client, NetStream.Publish.Denied, "Stream name not allowed for the logged in user: "+streamName);
			client.rejectConnection();
		}
		else{
			 invokePrevious(client, function, params);
		}

	}

Function when publisher disconnects from server . It removes the client from publisherClients.

	public void onDisconnect(IClient client)
	{
		if(this.publisherClients!=null){
			this.publisherClients.remove(client.getClientId());
		}
	}

The function to extract a streamname is


public String extractStreamName(IClient client, RequestFunction function, AMFDataList params)
{
String streamName = params.getString(PARAM1);
if (streamName != null)
{
String streamExt = MediaStream.BASE_STREAM_EXT;

String[] streamDecode = ModuleUtils.decodeStreamExtension(streamName, streamExt);
streamName = streamDecode[0];
streamExt = streamDecode[1];
}

return streamName;
}

The fucntion to check if streamname is allowed for the given user


public boolean isStreamNotAllowed(IClient client, String streamName)
{
WMSProperties localWMSProperties = client.getAppInstance().getProperties();
String allowedStreamName = localWMSProperties.getPropertyStr(this.publisherClients.get(client.getClientId()));
String sName="";
if(streamName.contains("?"))
sName = streamName.substring(0, streamName.lastIndexOf(&amp;amp;quot;?&amp;amp;quot;));
else
sName = streamName;
return !sName.toLowerCase().equals(allowedStreamName.toLowerCase().toString()) ;
}

On adding the application to wowza server make sure that the ModuleCoreSecurity is present under Modules in Application.xml

<Module>
<Name>ModuleCoreSecurity</Name>
<Description>Core Security Module for Applications</Description>
<Class>com.wowza.wms.security.ModuleCoreSecurity</Class>
</Module>

Also ensure that property securityPublishRequirePassword is present under properties

<Property>
<Name>securityPublishRequirePassword</Name>
<Value>true</Value>
<Type>Boolean</Type>
</Property>

Add the user credentials as properties too. For example to give access to testuser with password 123456 to stream on myStream include the following ,

<Property>
<Name>testUser</Name>
<Value>myStream</Value>
<Type>String</Type>
</Property>

Also include the mapping of user and password inside of conf/publish.password file

# Publish password file (format [username][space][password])
#username password

testuser 123456

Advertisements

Wowza RTMP Authenticate Module

To purpose of the article is the use the RTMP Authentication Module in wowza Engine .  This will enable us to intercept a connect request with username and password to be checked from any outside source like – database , password file , third party token provider , third party oauth etc.  Once the password provided by user is verified with the authentic password form external sources the user is allowed to connect and publish.

Step 1 : Create a new Wowza Media Server Project in Eclipse .  It is assumed that user has already integrated WowzaIDE into eclipse .

File -> New -> Wowza Media Server Project  

Step 2: Give any project name . I named it as “RTMPAuthSampleCode”.

wowza RTMP Auth

wowza RTMP Auth

Step 3 :   Point the location to existing Wowza Engine installed in local environment .

It is usually in /usr/local/WowzaStreamingEngine/

Wowza RTMP Auth

Wowza RTMP Auth

Step 4 : Proceed with the creation , uncheck the event methods as we are not using them right now .

Screenshot from 2015-09-17 13:10:24

Step 5: Put the code in class.

The class RTMPAuthSampleCode extends AuthenticateUsernamePasswordProviderBase . Its mandatory to define getPassword(String username ) and userExists(String username).  ModuleRTMPAuthenticate will invoke getPassword for connection request from users .

Screenshot from 2015-09-17 13:11:58

We can add any source of obtaining password for a given username which will be matched to the password supplied by user . If it matches he will be granted access otherwise we can return null or error message .

We may use various ways of obtaining user credentials like databse , password files , third part token provider etc . I will be discussing more ways to do RTMP authenticate esp using a third part token provider which using TEA.encrypt and shared secret in the next blog.

Step 6: Build the project and Run.

Project-> Build the Project 

Run -> Run Configurations … -> WowzaMediaServer_RTMPAuthSampleCode

To modules in my ubuntu 64 bit   version 14.04 system , I also need to provide

-Dcom.wowza.wms.native.base=”linux” inside of the VM Arguments . Its highlighted in figure below.

Screenshot from 2015-09-17 13:12:23

Step 7: Click Run to start the wowza Media Engine

Step 8 : Open the Manager Console of Wowza.

web based GUI interface of managing the application and checking for incoming streams . The manager script can be started with

sudo ./usr/local/WowzaStreamingEngine/manager/bin/startmgr.sh

The console can be opened at http://127.0.0.1:8088

Screenshot from 2015-09-17 13:53:58

Also you can see that RTMPAuthSampleCode.jar would have been copied to /usr/local/WowzaStreamingEngine/lib folder.

Step 9: Add module to applications

Add folder “RTMPAuthSampleCode” inside /usr/local/WowzaStreamingEngine/applications folder .

Step 10 : Add conf

Add folder “RTMPAuthSampleCode” inside /usr/local/WowzaStreamingEngine/conf  folder

Copy paste Application.xml from conf folder inside RTMPAuthSampleCode folder and make the following changes .

Add the ModuleRTMPAuthenticate module to Modules

<Module> <Name>ModuleRTMPAuthenticate</Name> <Description>ModuleRTMPAuthenticate</Description> <Class>com.wowza.wms.security.ModuleRTMPAuthenticate</Class> </Module>

and comment ModuleCoreSecurity

<!--    <Module>
     <Name>ModuleCoreSecurity</Name>
     <Description>Core Security Module for Applications</Description>
     <Class>com.wowza.wms.security.ModuleCoreSecurity</Class>
</Module> -->

Step 11: Add property usernamePasswordProviderClass to Properties .

usualy present inside Application at the bootom of Application.xml file

<Property>
<Name>usernamePasswordProviderClass</Name>
<Value>com.wowza.wms.example.authenticate.RTMPAuthSampleCode</Value>
</Property>

Step 12 : Make Authentication.xml file inside /usr/local/WowzaStreamingEngine/conf folder.

Note that from wowza 4 and later versions the Authentiocation.xml has come bundled with wms-server.jar which is inside of lib folder .   However for me , without giving a explicit Authentication.xml file the program froze and using my own simple authentication.xml gave problems with the digest . Hence follow the below process to get a working Authentication.xml file inside conf folder

Expand the archive and  inside the extracted folder wms-server copy the file from location wms-server/com/wowza/wms/conf/Authentication.xml to /usr/local/WowzaStreamingEngine/conf.

Step 13 : Restart Wowza Media Engine .

Step 14 : Use any RTMP encoder as Adobe Live Media Encoder or Gocoder or your own app ( could not use this with ffmpeg ) and  try to connect to application RTMPAuthSampleCode with username test and password 1234.

Step 15 : Observer the logs for incoming streams and traces from getpassword  .

 If you want the user test to have permission to publish stream to this application then return 1234 from getPassword else return null .

References :

  1. Media security overview
    http://www.wowza.com/forums/content.php?115-MediaSecurity-AddOn-Package-(SecureToken-RTMP-RTSP-Authentication-and-more
  2. How to integrate Wowza user authentication with external authentication systems (ModuleRTMPAuthenticate)
    http://www.wowza.com/forums/content.php?236-How-to-integrate-Wowza-user-authentication-with-external-authentication-systems-%28ModuleRTMPAuthenticate%29
  3. How to enable username/password authentication for RTMP and RTSP publishing
    http://www.wowza.com/forums/content.php?449-How-to-enable-username-password-authentication-for-RTMP-and-RTSP-publishing
  4. configuration ref 4.2 http://www.wowza.com/resources/WowzaStreamingEngine_ConfigurationReference.pdf