1. 用url参数传递用户名和密码,用文本文件存储用户名和密码
下面的代码例子展现了如何使用服务端API对RTMP流媒体播放请求进行访问控制,在这个例子中使用了一个基于文件的username/password认证方式。
package com.wowza.wms.plugin.collection.module;
import java.io.*;
import java.util.*;
import com.wowza.util.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.application.*;
import com.wowza.wms.authentication.*;
import com.wowza.wms.authentication.file.*;
import com.wowza.wms.client.*;
import com.wowza.wms.module.*;
import com.wowza.wms.request.*;
import com.wowza.wms.util.*;
import com.wowza.wms.vhost.*;
public class ModuleOnConnectAuthenticate2 extends ModuleBase
{
public static final String AUTHPASSWORDFILEPATH = "${com.wowza.wms.context.VHostConfigHome}/conf/connect.password";
private File passwordFile = null;
private String usernamePasswordProviderClass = null;
public void onAppStart(IApplicationInstance appInstance)
{
WMSProperties props = appInstance.getProperties();
String passwordFileStr = props.getPropertyStr("rtmpAuthenticateFile", AUTHPASSWORDFILEPATH);
this.usernamePasswordProviderClass = props.getPropertyStr("usernamePasswordProviderClass", this.usernamePasswordProviderClass);
if (passwordFileStr != null)
{
Map<String, String> envMap = new HashMap<String, String>();
IVHost vhost = appInstance.getVHost();
envMap.put("com.wowza.wms.context.VHost", vhost.getName());
envMap.put("com.wowza.wms.context.VHostConfigHome", vhost.getHomePath());
envMap.put("com.wowza.wms.context.Application", appInstance.getApplication().getName());
envMap.put("com.wowza.wms.context.ApplicationInstance", appInstance.getName());
passwordFileStr = SystemUtils.expandEnvironmentVariables(passwordFileStr, envMap);
passwordFile = new File(passwordFileStr);
}
if (passwordFile != null)
getLogger().info("ModuleOnConnectAuthenticate: Authorization password file: "+passwordFile.getAbsolutePath());
if (usernamePasswordProviderClass != null)
getLogger().info("ModuleOnConnectAuthenticate: Authorization password class: "+usernamePasswordProviderClass);
}
public void onConnect(IClient client, RequestFunction function, AMFDataList params)
{
boolean isAuthenticated = false;
String username = null;
String password = null;
try
{
while(true)
{
getLogger().info("size: " + params.size());
String[] auth = client.getQueryStr().split("&");
username = auth[0];
password = auth[1];
if (username == null || password == null)
break;
IAuthenticateUsernamePasswordProvider filePtr = null;
if (usernamePasswordProviderClass != null)
filePtr = AuthenticationUtils.createUsernamePasswordProvider(usernamePasswordProviderClass);
else if (passwordFile != null)
filePtr = AuthenticationPasswordFiles.getInstance().getPasswordFile(passwordFile);
if (filePtr == null)
break;
filePtr.setClient(client);
String userPassword = filePtr.getPassword(username);
if (userPassword == null)
break;
if (!userPassword.equals(password))
break;
isAuthenticated = true;
break;
}
}
catch(Exception e)
{
getLogger().error("ModuleOnConnectAuthenticate.onConnect: "+e.toString());
isAuthenticated = false;
}
if (!isAuthenticated)
client.rejectConnection("Authentication Failed["+client.getClientId()+"]: "+username);
else
client.acceptConnection();
}
}
编译后的模块包含在Wowza Modules 集合中。
下载并解开压缩包,将/lib/wms-plugin-collection.jar文件拷贝到Wowza /lib 文件夹下。然后重启Wowza Streaming Engine。这个模块的使用方法
-
在[install-dir]/conf文件夹下创建一个文本文件,命名为connect.password,在每个新的一行添加一个用户名和密码(用空格分割开):
[install-dir]/conf/connect.password:
user1 pass1 user2 pass2
-
将下面的模块添加到需要认证的应用的Application.xml文件的模块列表中:
<Module> <Name>moduleOnConnectAuthenticate2</Name> <Description>ModuleOnConnectAuthenticate2</Description> <Class>com.wowza.wms.plugin.collection.module.ModuleOnConnectAuthenticate2</Class> </Module>
2. 用url参数传递用户名和密码,用Mysql数据库存储用户名和密码
这个例子使用MySQL数据存储用户名和密码。
- 下载官方的JDBC driver for MySQL.
- 解压缩下载包后,将mysql-connector-java-5.0.5-bin.jar 拷贝到Wowza的安装路径的[install-dir]/lib下。
服务端Java代码类似如下:
package com.mycompany.wms.dbtest; import java.sql.*; 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.*; public class DBTest extends ModuleBase { public void onAppStart(IApplicationInstance appInstance) { // preload the driver class try { Class.forName("com.mysql.jdbc.Driver").newInstance(); } catch (Exception e) { getLogger().error("Error loading: com.mysql.jdbc.Driver: "+e.toString()); } } public void onConnect(IClient client, RequestFunction function, AMFDataList params) { String userName = getParamString(params, PARAM1); String password = getParamString(params, PARAM2); Connection conn = null; try { conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb"); Statement stmt = null; ResultSet rs = null; try { stmt = conn.createStatement(); rs = stmt.executeQuery("SELECT count(*) as userCount FROM users where username = '"+userName+"' and password = '"+password+"'"); if (rs.next() == true) { if (rs.getInt("userCount") > 0) { client.acceptConnection(); } } } catch (SQLException sqlEx) { getLogger().error("sqlexecuteException: " + sqlEx.toString()); } finally { // it is a good idea to release // resources in a finally{} block // in reverse-order of their creation // if they are no-longer needed if (rs != null) { try { rs.close(); } catch (SQLException sqlEx) { rs = null; } } if (stmt != null) { try { stmt.close(); } catch (SQLException sqlEx) { stmt = null; } } } conn.close(); } catch (SQLException ex) { // handle any errors System.out.println("SQLException: " + ex.getMessage()); System.out.println("SQLState: " + ex.getSQLState()); System.out.println("VendorError: " + ex.getErrorCode()); } getLogger().info("onConnect: " + client.getClientId()); } static public void onConnectAccept(IClient client) { getLogger().info("onConnectAccept: " + client.getClientId()); } static public void onConnectReject(IClient client) { getLogger().info("onConnectReject: " + client.getClientId()); } static public void onDisconnect(IClient client) { getLogger().info("onDisconnect: " + client.getClientId()); } } - 编辑Application.xml文件,在<Modules>列表中添加这个模块,然后将Connections/AutoAccept 设置为 false.
