ONVIF 自定义soap结构体实现用户认证
来源:互联网 发布:用矩阵解决实际问题 编辑:程序博客网 时间:2024/05/15 23:43
</pre><p>ONVIF 用户校验实现</p><p><span style="white-space:pre"></span>ONVIF 开发使用C/C++的话,使用 gsoap 这个工具是好用的。直接生成代码框架。以下是使用 gSOAP 自己修改框架完成用户认证的方法,</p><p><ol><li>gSOAP 生成的代码框架,在stdsoap2.c 文件的 struct SOAP_STD_API soap { ... } 结构体里面添加一个结构体 struct WS_UsernameToken SUsernameToken; 用来保存每条指令传过来的用户名,密码校验等信息。</li></ol></p><p></p><pre name="code" class="cpp">#define AUTHENTICATION_NAME_LEN 64struct WS_UsernameToken{ char m_acSoapUsername[AUTHENTICATION_NAME_LEN]; char m_acSoapPassword[AUTHENTICATION_NAME_LEN]; char m_acSoapPasswordType[AUTHENTICATION_NAME_LEN*2]; char m_acSoapNonce[AUTHENTICATION_NAME_LEN]; char m_acSoapCreated[AUTHENTICATION_NAME_LEN];};
因为gSOAP生成的代码框架,每条请求都携带一个 struct soap * 指针,所以把结构体存在这个 结构很合理。回调函数指针也应该存储在这个结构体。
2. 从请求指令里获取客户端传过来的用户名密码等信息
soapC.c 文件的 soap_in_SOAP_ENV__Header() 这个函数 (这个函数是gSOAP生成),是请求消息头域分析函数,从这里可以得到ONVIF定义的SOAP头域的所有字段。
仿照 soap_in_SOAP_ENV__Header() 函数内部的写法,添加以下代码,获取用户名密码头域。
//Michael Addsize_t soap_flag_auth = 1;//Michael Add//Michael Addif ( soap_flag_auth && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG ){if ( soap_in_PointerTo_Authentication(soap) == 0 ){soap_flag_auth--;continue;}}//Michael Add
soap_in_PointerTo_Authentication()这个函数也是仿照 gSOAP 生成框架的代码格式编写的,如下:
//Michael Addint soap_in_PointerTo_Password(struct soap *soap,char **password,char **passwordType){//if (soap_element_begin_in(soap,"wsse:Password",1,NULL))//return 1;if (soap_s2string(soap,soap_attr_value(soap,"Type",0),passwordType,0,-1))return 1;if (!soap_in_string(soap,"wsse:Password",password,"xsd:string"))return 1;//Type http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest//if ( soap_element_end_in(soap,"wsse:Password") )//return 1;return SOAP_OK;}
int soap_in_PointerTo_Authentication(struct soap *soap){ size_t soap_flag_Username = 1; size_t soap_flag_Password = 1; size_t soap_flag_Nonce = 1; size_t soap_flag_wsu__Created = 1;char *username = NULL ;char *password = NULL ;char *passwordType = NULL ;char *nonce = NULL;char *created = NULL; struct WS_UsernameToken UsernameToken;memset(&UsernameToken,0,sizeof(struct WS_UsernameToken)); if (soap_element_begin_in(soap, "wsse:Security", 1, NULL) != 0 ) return 1; if ( soap_element_begin_in(soap,"wsse:UsernameToken",1,NULL) != 0 ) return 1; for(;;) { soap->error = SOAP_TAG_MISMATCH; if ( soap_flag_Username && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG )) if ( soap_in_string(soap,"wsse:Username",&username,"xsd:string") ) { soap_flag_Username-- ; continue; } if (soap_flag_Password && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG ) ) //if ( soap_in_string(soap,"wsse:Password",&password,"xsd:string") )if( soap_in_PointerTo_Password(soap,&password,&passwordType)){ soap_flag_Password-- ; continue; } if (soap_flag_Nonce && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG ) ) if ( soap_in_string(soap,"wsse:Nonce",&nonce,"xsd:string") ) { soap_flag_Nonce-- ; continue; } if (soap_flag_wsu__Created && (soap->error == SOAP_TAG_MISMATCH || soap->error == SOAP_NO_TAG ) ) if ( soap_in_string(soap,"wsu:Created",&created,"xsd:string") ) { soap_flag_wsu__Created-- ; continue; } if (soap->error == SOAP_TAG_MISMATCH) soap->error = soap_ignore_element(soap); if (soap->error == SOAP_NO_TAG) break; if (soap->error) return 1; } soap_element_end_in(soap, "wsse:UsernameToken"); soap_element_end_in(soap, "wsse:Security");memset(soap->SUsernameToken.m_acSoapUsername,0,AUTHENTICATION_NAME_LEN);memset(soap->SUsernameToken.m_acSoapPassword,0,AUTHENTICATION_NAME_LEN);memset(soap->SUsernameToken.m_acSoapPasswordType,0,AUTHENTICATION_NAME_LEN*2);memset(soap->SUsernameToken.m_acSoapCreated,0,AUTHENTICATION_NAME_LEN);memset(soap->SUsernameToken.m_acSoapNonce,0,AUTHENTICATION_NAME_LEN);if ( username != NULL ){strcpy(soap->SUsernameToken.m_acSoapUsername,username);}if ( password != NULL ){strcpy(soap->SUsernameToken.m_acSoapPassword,password);}if ( passwordType != NULL ){strcpy(soap->SUsernameToken.m_acSoapPasswordType,passwordType);}if ( created != NULL ){strcpy(soap->SUsernameToken.m_acSoapCreated,created);}if ( nonce != NULL ){strcpy(soap->SUsernameToken.m_acSoapNonce,nonce);}return SOAP_OK;}//Michael Add
3 得到用户名密码等信息后,校验
在每条指令调用的函数,都携带了 struct soap ×的结构体指针,获取出来之后,就可以,使用 SHA1 算法进行密码校验了。具体算法请参考ONVIF 编程手册[ONVIF_WG-APG-Application_Programmer's_Guide] ,这个文档可以从ONVIF官方下载。
需要使用 SHA1 算法,请参考我的博客文章,有SHA1的实现。base64算法在gSOAP代码里面可以找到。
继续在 struct soap结构体里定义回调函数,完成用户认证应该困难不大了。
0 0
- ONVIF 自定义soap结构体实现用户认证
- Apache 自定义用户认证
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif规范的实现:使用gSOAP创建SOAP调用实例 .
- onvif规范的实现:使用gSOAP创建SOAP调用实例
- onvif学习 SOAP WSDL
- 如何自定义Tomcat Realm实现我们的用户认证需求
- 如何自定义Tomcat Realm实现我们的用户认证需求
- 如何自定义Tomcat Realm实现我们的用户认证需求
- spring and ssh 整合
- CSS优先级,优先级计算
- C语言中char * 与char[]详解
- QPSK信号调制与解调
- 圣杯布局
- ONVIF 自定义soap结构体实现用户认证
- Graps/白鸡百钱/七星彩
- 【iOS开发-56】案例BUG:按钮的enabled、控件的userInteractionEnabled以及两种提示框UIAlert和UIActionSheet
- C Char* Char[] sizeof
- arcmap坐标点生成线和面(更正版)
- Ubuntu 11.04 下安装配置 JDK 7
- 我的自述,我的自我评价,认识自己,升华自己
- 一个完整的项目流程是确保项目顺利进行的关键
- 用VS2013建一个C++程序