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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s