Wowza Community

LDAP authorization example

I’m not much of a Java programmer but I’ve coded a module that authorizes against an LDAP server. Here is the working code:

package com.example.wms.module;

import com.wowza.wms.application.*;

import com.wowza.wms.amf.*;

import com.wowza.wms.client.*;

import com.wowza.wms.module.*;

import com.wowza.wms.request.*;

import javax.naming.*;

import javax.naming.directory.*;

import java.util.Hashtable;

public class LDAPAuth extends ModuleBase {

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

{

String username = getParamString(params, PARAM1, “”).trim();

String password = getParamString(params, PARAM2, “”).trim();

if (("").equals(username) || ("").equals(password))

{

System.out.println(“Empty string or password”);

}

else

{

String base = “ou=People,dc=example,dc=com”;

String dn = “cn=” + username + “,” + base;

String ldapURL = “ldap://ldap.example.com:389”;

Hashtable authEnv = new Hashtable();

authEnv.put(Context.INITIAL_CONTEXT_FACTORY,“com.sun.jndi.ldap.LdapCtxFactory”);

authEnv.put(Context.PROVIDER_URL, ldapURL);

authEnv.put(Context.SECURITY_AUTHENTICATION, “simple”);

authEnv.put(Context.SECURITY_PRINCIPAL, dn);

authEnv.put(Context.SECURITY_CREDENTIALS, password);

try

{

DirContext authContext = new InitialDirContext(authEnv);

client.acceptConnection();

getLogger().info("onConnect: " + client.getClientId());

return;

}

catch (AuthenticationException authEx)

{

System.out.println("AuthenticationException: " + authEx.getMessage());

}

catch (NamingException namEx)

{

System.out.println("NamingException: " + namEx.getMessage());

}

}

client.rejectConnection();

getLogger().info("onConnect: " + client.getClientId());

}

public void onConnectAccept(IClient client) {

getLogger().info("onConnectAccept: " + client.getClientId());

}

public void onConnectReject(IClient client) {

getLogger().info("onConnectReject: " + client.getClientId());

}

public void onDisconnect(IClient client) {

getLogger().info("onDisconnect: " + client.getClientId());

}

}

I used Charlie’s example (http://www.wowza.com/community/t/-/113) for the basics. I guess I’m wondering if there’s any improvements I can make. What I found interesting was that unlike Charlie’s code I had to explicitly call client.rejectConnection() or the connection would still be accepted. Not sure why.

Building on this, I have a security model that I’m developing and I was hoping for input on how effective it might be. I believe the encryption offered by RTMPE is adequate for streams but I’m not comfortable using it for LDAP passwords so I plan on authorising with RTMPS and then reconnecting for the actual streaming with RTMPE (for server performance). Here’s my plan:

  1. On instantiation of client Flash movie generate a random hash.

  2. Send (over RTMPS) username, password and client hash.

  3. On successful connection (using code above), generate random hash on the server, send back to client and close connection. Store client hash, server hash and timestamp in array (Hashtable?) on server.

  4. Client immediately makes new connection sending client hash and server hash. On successful connection (lookup element in array), relevant element is deleted from array. Otherwise connection rejected. A parameter in the connection method, “simple” or “token”, could determine whether the other params should be considered username/passwords or tokens (to differentiate between connection types).

  5. Repeat steps 2-4 each time a new stream is requested.

  6. Because this has the ability to cause a memory leak if elements in the array are not used or deleted, some sort of timer-based cleanup function would need to run to remove any elements whose timestamps are greater than, for example, two minutes (assuming a successful connection would only take a second or two). This process should not be too intensive as the array would only contain elements relating to failed connections.

Any suggestions?

Specifically:

a) Is it secure?

b) I think this would mean that using securetoken would be redundant?

c) As I don’t know Java or Wowza very intimately, should i use a Java timer to clean up the array or is there a regular Wowza process I can hook into?

d) Lastly a dumb Java/Wowza question, do instances of the custom module classes persist until Wowza is shutdown? That is, if I declare an array/hashtable variable and timer function in my module, will they persist?

Sorry for the length of this post. I hope at least the code is useful.

SecureToken protects content in the client, so it would not be redundant. If you trust the users that are authenticated and you trust the authentication method, SecureToken may not be necessary.

A Wowza application module has the same scope as the application. If the application is idle for about a minute it will unload.

You can use onDisconnect for cleanup, or a timer I suppose.

Otherwise, I’m not really sure how, where, if to jump in. Development seems to be going okay, I would keep working on it. On our side, we don’t want to get too involved in development at a certain level that might as well be co-working on a project.

Richard

Thanks so much for your reply, rrlanham. No faux co-development required - just wondered if there was anything blindingly obvious that I was doing wrong.

I’m not exactly sure what you mean by “protects content in the client” but I can see that SecureToken might provide another level of assurance that the SWF is trusted. A very small level I think as I don’t know how I could stop someone from decompiling the client SWF to get the shared secret. Are there any techniques that you’re aware of to protect the shared secret? Do any of those SWF encrypting programs work for example?

Thanks for the tip about onDisconnect. I think in this case I might try the timer approach first as I’ll probably initially run the cleanup function every two minutes and I expect disconnections to happen much more frequently than that. The resources spent will probably be trivial in both cases regardless.

Thanks again for your help. It’s a credit to you that you even read to the end of my post!

This is a shot in the dark, but are you still on this forum dazweeja? I’d be interested in seeing if/how you got this working…