今天完成了GA身份验证模块的实现,具体的功能描述:由于GA面向的是平台用户,只有在我们平台注册了的用户才可以启动我们的应用程序,因此在GA的服务端必须加上用户身份的认证,这就是认证模块开发的初衷。在我们的环境中采用的是Windows AD(活动目录)服务器,我利用的开发库是Novell公司提供的openldap的库,相关的下载地址我会在下面给出,通过它完全可以实现对Windows AD的组织单元中用户实体的增、删、改、查。
参考链接:http://www.novell.com/documentation/developer/samplecode/cldap_sample/ ,这里面用详细的例子实现了如果操作ldap服务器,用它完全可以满足你的需求。
下面我将分三部分说明GA中认证模块是如何实现的:
1> 用户名username和密码password是如何传递的;
2> GA服务端是如何实现用户认证的;
3> GA服务端如何将认证结果返回给客户端的;
第一部分:username和password是如何传递的
在前面的GA实现并发请求的时候我们已经将了特定的游戏名称是如何发送到服务端的,这里的实现方式与它相同,同样是拼接在客户端的启动参数中,它的最终形式例如:rtsp://10.3.1.10:8554/LocalDeformablePRT/houqd_forh30/123456,其中红色标出的部分一次为:游戏名gamename , 用户名username,密码password。只要将需要的参数拼接在上面,在live555实现的RTSP的客户端执行:rtspClient->sendOptionsCommand(continueAfterOPTIONS);后,它就会把在RTSP的OPTIONS阶段将整个URL发送到GA的服务器端,而我们需要做的就是在服务器端将该参数解析出来,很简单吧,下面是服务器端的解析代码:
// added by houqd , parse specifical string , like "LocalDeformablePRT/houqd_forh3/123456"
/*
param:
[In] value : the addr of specifical string
[In] sign : the separator in string
[Out] c : the count of string separated by sign
return:
Array of separated by sign
*/
char** parseValue(char** value , const char sign , int *c)
{
char *val = *value ;
char s = sign ;
char **result = NULL ;
int count = 0 ;
int i = 0 ;
int j = 0 ;
while((*val)!=' ' && (*val)!='\0')
{
printf("%c" , *val);
if((*val) == sign){
count++;
}
val++ ;
}
*c = count ;
result = (char **)malloc(sizeof(char *)*(count+1));
if(result == NULL){
fprintf(stderr , "[houqd] malloc execute error.\n");
}else{
fprintf(stderr , "[houqd] malloc execute successed.\n");
}
for(int k = 0 ; k <= count ; k++){
result[k] = (char *)malloc(sizeof(char)*1024);
}
val = *value ;
while( (*val)!=' ' && (*val)!='\0' ){
if((*val) != s){
result[i][j++] = *val ;
}else{
result[i][j] = '\0';
j = 0 ;
i++;
}
val++ ;
}
result[i][j] = '\0';
return result ;
}
// 调用的代码
// added by houqd 2014/02/24 , get username and passwd
strcpy(value, strstr(url, "8554")+5);
valueCopy = value ;
parseValueRes = parseValue(&valueCopy , '/' , &parseValueCount);
if(parseValueRes == NULL){
fprintf(stderr , "houqd .. parse username and passwd error.\n");
}else{
appname = parseValueRes[0]; // 游戏名称
username = parseValueRes[1]; // 用户名
passwd = parseValueRes[2]; // 密码
}
第二部分:GA服务端实现用户身份认证
这里需要提到两点,一是:GA服务端认证部分代码结构的实现;二是:C操作ldap身份认证的实现。
1)为了和GA服务端原有代码结构保持一致,单独新建了子项目adldap来为用户身份认证提供接口,adldap子项目创建的是DLL工程,我们最终使用它的dll和lib文件,采用隐式调用(不采用LoadLibrary()的方式load dll文件)的方式来使用他们。最终的项目结构关系为:
2)用户身份认证部分,在GA的server端要实现的只是用户身份的认证,而不需要增加删除和修改的功能。因为添加用户、删除用户以及修改用户信息,在平台的Web端都实现了。由于在Windows AD schema设计的原因,在用户实体的属性中我们无法获得用户的密码信息,而只能得到用户名,那这样如何实现密码的验证呢?通过在Stack Overflow的搜索得知验证用户密码的方式:先查找用户名,如果用户名存在的情况下执行ldap_simple_bind_s(),利用给定的用户名和密码进行二次连接,如果此时能够连上则说明用户身份认证通过,用户名和密码都正确,如果无法连接则说明密码错误;如果连用户名都无法查到&#x