In main.asc, check the value of client.ip and, if needed, reject the client’s connection to the application:
Use properties of the Client object
When a client connects to an application, the server creates a Client object that contains information about the client and passes it to the application.onConnect() handler in Server-Side ActionScript. You can write server-side code to access the properties of the Client object and use the values to verify the validity of the connecting client:
application.onConnect = function( pClient ) { for (var i in pClient) { trace( "key: " + i + ", value: " + pClient[i] ); } }
Check the client’s IP address
-
if (client.ip.indexOf("60.120") !=0) { application.rejectConnection(client, {"Access Denied"} ); }
Check an originating URL
-
In main.asc, check the value of client.referrer against a list of URLs that should be denied access. Make sure that SWF files that are connecting to your application are coming from a location you expect. If you find a match, reject the client’s connection:
referrerList = {}; referrerList["http://www.example.com"] = true; referrerList["http://www.abc.com"] = true; if (!referrerList[client.referrer]) { application.rejectConnection(client, {"Access Denied"} ); }
Use a unique key
-
In client-side ActionScript, create a unique key, as in the following code, which concatenates the local computer time with a random number:
var keyDate = String(new Date().getTime()); var keyNum = String(Math.random()); var uniqueKey = keyDate + keyNum;
-
Send the key to the server in the connection request:
nc.connect("rtmp://www.example.com/someApplication", uniqueKey);
-
The following code in the main.asc file looks for the unique key in the connection request. If the key is missing or has already been used, the connection is rejected. This way, if a connection is replayed by an imposter, the replay attempt fails.
clientKeyList = new Object(); // holds the list of clients by key application.onConnect = function( pClient, uniqueKey ) { if ( uniqueKey != undefined ) { // require a unique key with connection request if ( clientKeyList[uniqueKey] == undefined ) { // first time -- allow connection pClient.uniqueKey = uniqueKey; clientKeyList[uniqueKey] = pClient; this.acceptConnection(pClient); } else { trace( "Connection rejected" ); this.rejectConnection(pClient); } } } application.onDisconnect = function( pClient ) { delete clientKeyList[pClient.uniqueKey]; }
Use an Access plug-in
An Access plug‑in intercepts incoming requests before passing them to the application. You can program an Access plug‑in to use any form of authentication.
Use Flash Player version
You can protect your content from clients that aren’t running in Flash Player, based on the user agent string received from the connection. The user agent string identifies the platform and Flash Player version, for example:
WIN 8,0,0,0 MAC 9,0,45,0
There are two ways to access these strings:
Virtual keys
Configure the server to remap the stream based on the Flash Player client.
Client.agent
Challenge the connection using Server-Side ActionScript:
application.onConnect = function( pClient ) { var platform = pClient.agent.split(" "); var versionMajor = platform[1].split(",")[0]; var versionMinor = platform[1].split(",")[1]; var versionBuild = platform[1].split(",")[2]; } // output example // Client.agent: WIN 9,0,45,0 // platform[0]: "WIN" // versionMajor: 9 // versionMinor: 0 // versionBuild: 45Verify connecting SWF files
You can configure the server to verify the authenticity of client SWF files before allowing them to connect to an application. Verifying SWF files prevents someone from creating their own SWF files that attempt to stream your resources. SWF verification is supported in Flash Player 9 Update 3 and later.
Allow or deny connections from specific domains
If you know the domains from which the legitimate clients will be connecting, you can whitelist those domains. Conversely, you can blacklist known bad domains.
You can enter a static list of domain names in the Adaptor.xml file.
You can also maintain these lists in your own server-side code and files. In the following example, a file named bannedIPList.txt contains a list of excluded IP addresses, which can be edited on the fly:
// bannedIPList.txt file contents: // 192.168.0.1 // 128.493.33.0 function getBannedIPList() { var bannedIPFile = new File ("bannedIPList.txt") ; bannedIPFile.open("text","read"); application.bannedIPList = bannedIPFile.readAll(); bannedIPFile.close(); delete bannedIPFile; } application.onConnect = function(pClient) { var isIPOK = true; getBannedIPList(); for (var index=0; index<this.bannedIPList.length; index++) { var currentIP = this.bannedIPList[index]; if (pClient.ip == currentIP) { isIPOK = false; trace("ip was rejected"); break; } } if (isIPOK) { this.acceptConnection(pClient); } else { this.rejectConnection(pClient); } }
In addition, you can create server-side code to check if requests are coming in too quickly from a particular domain:
application.VERIFY_TIMEOUT_VALUE = 2000; Client.prototype.verifyTimeOut = function() { trace (">>>> Closing Connection") clearInterval(this.$verifyTimeOut); application.disconnect(this); } function VerifyClientHandler(pClient) { this.onResult = function (pClientRet) { // if the client returns the correct key, then clear timer if (pClientRet.key == pClient.verifyKey.key) { trace("Connection Passed"); clearInterval(pClient.$verifyTimeOut); } } } application.onConnect = function(pClient) { this.acceptConnection(pClient); // create a random key and package within an Object pClient.verifyKey = ({key: Math.random()}); // send the key to the client pClient.call("verifyClient", new VerifyClientHandler(pClient), pClient.verifyKey); // set a wait timer pClient.$verifyTimeOut = setInterval(pClient, $verifyTimeOut, this.VERIFY_TIMEOUT_VALUE, pClient); } application.onDisconnect = function(pClient) { clearInterval(pClient.$verifyTimeOut); }