Hi,
Secure token will only allow a player with the correct token to connect to the Wowza Server. It will not stop someone from downloading your player and putting it on their own website.
Setting Connections/AutoAccept to false and Connections/AllowedDomains to your own domains in the Application.xml will prevent an swf from another domain from connecting to your server which will block someone who has downloaded your player or has compiled their own player with your token.
<Connections>
<AutoAccept>false</AutoAccept>
<AllowDomains>localhost,*yourswfdomain.com</AllowDomains>
</Connections>
ModuleHotlinkDenial will check the Web Page Referrer to see if it is allowed to connect to your server. It will not prevent someone from linking directly to your player swf file and passing the params in the link.
<Property>
<Name>domainLock</Name>
<Value>localhost,*yourwebdomain.com</Value>
</Property>
Web site Hotlink Protection will prevent someone from directly linking to the swf file.
None of the above will prevent someone from iframing your web page or player. The way to stop that is control access to the actual player and page. Require users to be logged in somehow but don’t make it automated.
All of these methods on their own can be bypassed fairly easily but combined make it difficult but not impossible for someone who is determined to bypass your security.
The best method would be to encrypt the stream name on your web server dynamically along with some other information that would be unique to the connection and would only be known by the web server and the Wowza server. When the request comes in, decrypt the stream name and check the information. If it passes, allow the stream to be played.
Example.
On the Web Server:
-
Have the following information:
-
Secret Value
-
Users ip address
-
Actual Stream Name
-
Current Timestamp
-
Any other values you want.
-
Create an MD5 hash of these values.
$hash = md5(<secret>:<ip>:<stream-name>:<timestamp>[:<any-other-values>])
-
The Wowza server will know the secret and the ip address but it needs the stream name and timestamp and any extra values. The more information you use, the harder it will be to bypass but could also lead to playback problems for legitimate users.
Create a base64 encode of the md5 hash and the other values that Wowza needs.
$name = base64Encode(<hash>:<stream-name>:<timestamp>[:<any-other-values>])
This base64 value is the stream name you use in the player. It will be unique for every player request and will work for all player types.
On the Wowza server, you would have to create a module that can decode the information and check it. This can be done with a module that implements the IMediaStreamNameAliasProvider(2) interface.
The interface has resolvePlayAlias methods where you would decode the information and allow or deny the stream playback. If you allow teh playback, you return the real stream name from this method. If you deny it then you return null.
The process the reverse to what is done on the web server.
-
Base64 decode the requested name to get the separate values.
String[] values = Base64.decode(name).split(":");
-
Create an md5 hash of the locally known values and the extra values extracted from the requested name.
String testStr = localSecret+":"+client.getIp(); // Start with the locally know information.
for(int i = 1; i < values.length; i++)
{
testStr += ":"+values[i]; // Add the information extracted from the requested name;
}
String localHash = MD5DigestUtils.generateHash(testStr);
boolean isGood = localHash.equalsIgnoreCase(values[0]));
if(isGood)
{
return values[1];
}
return null;
-
If this local has value matches what is extracted from the requested name then you are fairly confident that the connection is legitimate.
You can take this further by checking the timestamp is within a specified time frame or more than just 1 attempt is being made to play the stream or you can make a call back to the web server to validate any information further. Any of these callbacks would be invisible to the end user. You could invalidate the requested name after it has been used once but this would require the player to refresh for every play request.
This is just an example of what could be done. As you can see, it is a lot more work than the standard methods.
Roger.