鉴权过程如下:
客户端第一次请求 onvif 设备,如 onvif 设备验证 Authorization 失败,则响应 401,同时响应头包含 WWW-Authenticate
头信息(onvif 设备生成的随机数),客户端拿到该数据后根据下面公式计算 digest,再次请求,同时携带计算的 digest 数据即可成功请求。
客户端第一次请求
POST /onvif/PTZ HTTP/1.1
Host: 192.168.1.212
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 644
<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><AbsoluteMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>media_profile_token1</ProfileToken><Position><PanTilt x="0.01" y="0.01" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/><Zoom x="0" space="http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/></Position></AbsoluteMove></s:Body></s:Envelope>HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="IPC_CAM", qop="auth,auth-int", nonce="62fb10dacb7f08aa31fc", opaque="025f3a12"
Server: gSOAP/2.8
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 1707
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl"><SOAP-ENV:Body><SOAP-ENV:Fault><SOAP-ENV:Code><SOAP-ENV:Value>SOAP-ENV:Sender</SOAP-ENV:Value></SOAP-ENV:Code><SOAP-ENV:Reason><SOAP-ENV:Text xml:lang="en">HTTP Error: 401 Unauthorized</SOAP-ENV:Text></SOAP-ENV:Reason></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
客户端第二次请求
POST /onvif/PTZ HTTP/1.1
Host: 192.168.1.212
Content-Type: application/soap+xml; charset=utf-8
Authorization: Digest username="admin",realm="IPC_CAM",qop="auth",algorithm=MD5,uri="/onvif/PTZ",nonce="62fb10dacb7f08aa31fc",nc=00000001,cnonce="D12DE722E3B5C2BE8128768A68DE4209",opaque="025f3a12",response="1f73853bc5a5f6728e4f68b26d01065a"
Content-Length: 644
<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><AbsoluteMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>media_profile_token1</ProfileToken><Position><PanTilt x="0.01" y="0.01" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/><Zoom x="0" space="http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace" xmlns="http://www.onvif.org/ver10/schema"/></Position></AbsoluteMove></s:Body></s:Envelope>HTTP/1.1 200 OK
Server: gSOAP/2.8
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 1542
Connection: close
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:chan="http://schemas.microsoft.com/ws/2005/02/duplex" xmlns:wsa5="http://www.w3.org/2005/08/addressing" xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:wsc="http://schemas.xmlsoap.org/ws/2005/02/sc" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xmime="http://tempuri.org/xmime.xsd" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:wsrfbf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl"><SOAP-ENV:Body><tptz:AbsoluteMoveResponse></tptz:AbsoluteMoveResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
digest 计算部分如下
QString Onvif::calcDigest()
{
QString username = "admin";
QString realm = "IPC_CAM";
QString qop = "auth";
QString algorithm = "MD5";
QString uri = "/onvif/PTZ";
QString nonce = "62fa0f4ecaee87486d09";
QString nc = "00000001";
QString cnonce = "AA5187988E637D496C41C22809D08C8E";
QString opaque = "bcf3610f";
QString response = "f0b63294cce2664ffb7bfdcf887dde44";
// R"(Digest username="admin",realm="IPC_CAM",qop="auth",algorithm=MD5,uri="/onvif/PTZ",nonce="62fa0f4ecaee87486d09",nc=00000001,cnonce="AA5187988E637D496C41C22809D08C8E",opaque="bcf3610f",response="f0b63294cce2664ffb7bfdcf887dde44")";
/*!
HA1 = MD5(username:realm:password)
HA2 = MD5(method:uri)
response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)
*/
QString password = "123";
QString HA1 = QCryptographicHash::hash(QString("%1:%2:%3").arg(username).arg(realm).arg(password).toUtf8(),QCryptographicHash::Md5).toHex();
QString method = "POST";
QString HA2 = QCryptographicHash::hash(QString("%1:%2").arg(method).arg(uri).toUtf8(),QCryptographicHash::Md5).toHex();
QString eq_response = QCryptographicHash::hash(QString("%1:%2:%3:%4:%5:%6")
.arg(HA1)
.arg(nonce)
.arg(nc)
.arg(cnonce)
.arg(qop)
.arg(HA2)
.toUtf8()
,QCryptographicHash::Md5).toHex();
QString eq_cnonce = QCryptographicHash::hash(QByteArray::number(QDateTime::currentDateTimeUtc().currentSecsSinceEpoch()),QCryptographicHash::Md5).toHex();
qDebug() << "HA1:" << HA1;
qDebug() << "HA2:" << HA2;
qDebug() << "Response:" << eq_response;
qDebug() << eq_cnonce;
return "None";
}
https://www.cnblogs.com/lsdb/p/10621940.html