Onvif PullpointProxy Pullmessages返回错误401未经授权
Onvif PullPointProxy PullMessages returns error 401 Unauthorized
我正在尝试从ONVIF IP-CAMERA中获取运动检测器事件。我可以获取订阅的主题地址,但是当我尝试从中取出消息时,我会收到错误:
Error 401 fault detected[no subcode]
"HTTP/1.1 401 Unauthorized"
Detail: <!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error: Access Denied! Authorization required.</p>
</body>
</html>
我为每个请求创建了几个代理,例如DeviceProxy,EventsProxy,PullPointProxy和添加的安全标头和时间戳,但只有PullPointProxy无法授权它们。
void COnvifMotionDetectorWorker::AddSecurity(soap* pProxy, const bool& bAddWsse)
{
if(bAddWsse)
{
soap_wsse_add_Security(pProxy);
}
if(SOAP_OK != soap_wsse_add_UsernameTokenDigest(pProxy, "Auth", m_sUsername.c_str(), m_sPassword.c_str()))
{
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("Error adding username token"),
"COnvifMotionDetectorWorker::AddSecurity()",
std::string("DeviceId #") + m_sDeviceId);
}
if(SOAP_OK != soap_wsse_add_Timestamp(pProxy, "Time", 10))
{
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("Error adding timestamp"),
"COnvifMotionDetectorWorker::AddSecurity()",
std::string("DeviceId #") + m_sDeviceId);
}
}
void COnvifMotionDetectorWorker::Body()
{
DeviceBindingProxy DeviceProxy;
AddSecurity(&DeviceProxy, true);
DeviceProxy.soap_endpoint = m_sDeviceUrl.c_str();
_tds__GetCapabilities deviceCapabilities;
deviceCapabilities.Category.push_back(tt__CapabilityCategory__All);
_tds__GetCapabilitiesResponse deviceCapabilitiesResponse;
if(SOAP_OK == DeviceProxy.GetCapabilities(&deviceCapabilities, deviceCapabilitiesResponse))
{
if(deviceCapabilitiesResponse.Capabilities->Events != nullptr)
{
m_Logger.LogMessage(
NLogger2::ePriorityLevelInfo,
std::string("Device has event capabilities"),
"COnvifMotionDetectorWorker::BeforeBody()",
std::string("DeviceId #") + m_sDeviceId);
PullPointSubscriptionBindingProxy EventsProxy(
deviceCapabilitiesResponse.Capabilities->Events->XAddr.c_str());
EventsProxy.soap_endpoint = deviceCapabilitiesResponse.Capabilities->Events->XAddr.c_str();
AddSecurity(&EventsProxy, true);
_tev__GetEventProperties gep;
_tev__GetEventPropertiesResponse gepr;
if (EventsProxy.GetEventProperties(&gep, gepr) == SOAP_OK)
{
PrintOnvifParameter("Event: TopicNamespaceLocation");
for (size_t i = 0; i < gepr.TopicNamespaceLocation.size(); i++)
{
PrintOnvifParameter("", gepr.TopicNamespaceLocation.at(i).c_str());
}
PrintOnvifParameter("Event: fixedTopicSet", gepr.wsnt__FixedTopicSet ? "Yes" : "No");
PrintOnvifParameter("Event: Topics:");
if (gepr.wstop__TopicSet != NULL && gepr.wstop__TopicSet->documentation != NULL && gepr.wstop__TopicSet->documentation->__mixed != NULL)
{
PrintOnvifParameter("", gepr.wstop__TopicSet->documentation->__mixed);
}
else
{
PrintOnvifParameter("", "None");
}
PrintOnvifParameter("Event: MessageContentFilterDialect");
for (size_t i = 0; i < gepr.MessageContentFilterDialect.size(); i++)
{
PrintOnvifParameter("", gepr.MessageContentFilterDialect.at(i).c_str());
}
PrintOnvifParameter("Event: MessageContentSchemaLocation");
for (size_t i = 0; i < gepr.MessageContentSchemaLocation.size(); i++)
{
PrintOnvifParameter("", gepr.MessageContentSchemaLocation.at(i).c_str());
}
PrintOnvifParameter("Event: ProducerPropertiesFilterDialect");
for (size_t i = 0; i < gepr.ProducerPropertiesFilterDialect.size(); i++)
{
PrintOnvifParameter("", gepr.ProducerPropertiesFilterDialect.at(i).c_str());
}
PrintOnvifParameter("Event: wsnt__TopicExpressionDialect");
for (size_t i = 0; i < gepr.wsnt__TopicExpressionDialect.size(); i++)
{
PrintOnvifParameter("", gepr.wsnt__TopicExpressionDialect.at(i).c_str());
}
}
else
{
EventsProxy.soap_stream_fault(std::cerr);
PrintOnvifParameter("Error getting event profiles");
}
PrintOnvifParameter("Event: Creating pull point:");
AddSecurity(&EventsProxy, true);
_tev__CreatePullPointSubscription cpps;
_tev__CreatePullPointSubscriptionResponse cppr;
std::string termtime = "PT60S";
cpps.InitialTerminationTime = &termtime;
if (EventsProxy.CreatePullPointSubscription(&cpps, cppr) == SOAP_OK)
{
PrintOnvifParameter("Event: pull point subscription created:");
PrintOnvifParameter("termination time", std::to_string(cppr.wsnt__TerminationTime));
PrintOnvifParameter("SubscriptionReference.Address", cppr.SubscriptionReference.Address);
if (cppr.SubscriptionReference.__anyAttribute != nullptr)
{
PrintOnvifParameter("__anyAttribute", cppr.SubscriptionReference.__anyAttribute);
}
PrintOnvifParameter("SubscriptionReference.__size", std::to_string(cppr.SubscriptionReference.__size));
for (int i = 0; i < cppr.SubscriptionReference.__size; i++)
{
PrintOnvifParameter("__any", cppr.SubscriptionReference.__any[i]);
}
if (cppr.SubscriptionReference.Metadata != nullptr)
{
if (cppr.SubscriptionReference.Metadata->__anyAttribute != nullptr)
{
PrintOnvifParameter("Metadata->__anyAttribute",
cppr.SubscriptionReference.ReferenceParameters->__anyAttribute);
}
for (int i = 0; i < cppr.SubscriptionReference.Metadata->__size; i++)
{
PrintOnvifParameter("MetaData__any",
cppr.SubscriptionReference.Metadata->__any[i]);
}
}
if (cppr.SubscriptionReference.ReferenceParameters != nullptr)
{
if (cppr.SubscriptionReference.ReferenceParameters->__anyAttribute != nullptr)
{
PrintOnvifParameter("ReferenceParameter->__anyAttribute",
cppr.SubscriptionReference.ReferenceParameters->__anyAttribute);
}
PrintOnvifParameter("SubscriptionReference.ReferenceParameters->__size",
std::to_string(cppr.SubscriptionReference.ReferenceParameters->__size));
for (int i = 0; i < cppr.SubscriptionReference.ReferenceParameters->__size; i++)
{
PrintOnvifParameter("ReferenceParameter",
cppr.SubscriptionReference.ReferenceParameters->__any[i]);
}
}
// Set up proxy to read from subscription reference
std::string sSubscriptionAddress = cppr.SubscriptionReference.Address;
PullPointSubscriptionBindingProxy PullPointProxy(sSubscriptionAddress.c_str());
AddSecurity(&PullPointProxy, true);
while(!m_bExit)
{
_tev__PullMessages PullMessages;
PullMessages.Timeout = "PT10S";
PullMessages.MessageLimit = 100;
_tev__PullMessagesResponse PullMessagesResponse;
int nRetCode = SOAP_OK;
if ((nRetCode = PullPointProxy.PullMessages(&PullMessages, PullMessagesResponse)) == SOAP_OK)
{
for (auto msg : PullMessagesResponse.wsnt__NotificationMessage)
{
ProcessOnvifMessage(msg->Message.__any);
}
}
else
{
PullPointProxy.soap_stream_fault(std::cerr);
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("PullPointProxy.PullMessages() error code is ") + std::to_string(nRetCode),
"COnvifMotionDetectorWorker::Body()",
std::string("DeviceId #") + m_sDeviceId);
}
// Wait for nothing
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
}
else
{
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("No device events capabilities"),
"COnvifMotionDetectorWorker::BeforeBody()",
std::string("DeviceId #") + m_sDeviceId);
}
}
else
{
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("Error getting device capabilities"),
"COnvifMotionDetectorWorker::BeforeBody()",
std::string("DeviceId #") + m_sDeviceId);
}
// Wait for nothing before ending
std::this_thread::sleep_for(std::chrono::seconds(1));
}
运行程序中的日志是:
PrintOnvifParameter(): Event: TopicNamespaceLocation -
PrintOnvifParameter(): - http://www.onvif.org/onvif/ver10/topics/topicns.xml
PrintOnvifParameter(): Event: fixedTopicSet - Yes
PrintOnvifParameter(): Event: Topics: -
PrintOnvifParameter(): - None
PrintOnvifParameter(): Event: MessageContentFilterDialect -
PrintOnvifParameter(): - http://www.onvif.org/ver10/tev/messageContentFilter/ItemFilter
PrintOnvifParameter(): Event: MessageContentSchemaLocation -
PrintOnvifParameter(): - http://www.onvif.org/onvif/ver10/schema/onvif.xsd
PrintOnvifParameter(): Event: ProducerPropertiesFilterDialect -
PrintOnvifParameter(): Event: wsnt__TopicExpressionDialect -
PrintOnvifParameter(): - http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet
PrintOnvifParameter(): - http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete
PrintOnvifParameter(): Event: Creating pull point: -
PrintOnvifParameter(): Event: pull point subscription created: -
PrintOnvifParameter(): termination time - 1557833982
PrintOnvifParameter(): SubscriptionReference.Address - http://192.168.1.36/onvif/Events/PullSubManager_2019-05-14T11:38:42Z_1
PrintOnvifParameter(): __anyAttribute -
PrintOnvifParameter(): SubscriptionReference.__size - 0
请帮助了解为什么只有pullmessages返回错误以及正确身份验证需要哪些特定参数?
可能会持续...
问题是在WS-Addressing标题中:https://www.w3.org/submission/ws-addressing/https://www.genivia.com/doc/wsdd/html/wsa_0.html
我将其添加到我的PullMessage请求中,并从相机中收到了响应。
代码应为:
// Set up proxy to read from subscription reference
std::string sSubscriptionAddress = cppr.SubscriptionReference.Address;
PullPointSubscriptionBindingProxy PullPointProxy(sSubscriptionAddress.c_str());
AddSecurity(&PullPointProxy);
soap_register_plugin(&PullPointProxy, soap_wsa);
while(!m_bExit)
{
AddSecurity(&PullPointProxy, false);
if (SOAP_OK != soap_wsa_request(&PullPointProxy,
nullptr,
sSubscriptionAddress.c_str(),
"http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesRequest") ||
(SOAP_OK != soap_wsa_add_ReplyTo(&PullPointProxy,
"http://www.w3.org/2005/08/addressing/anonymous"))
)
{
PullPointProxy.soap_stream_fault(std::cerr);
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("soap_wsa_request error"),
"COnvifMotionDetectorWorker::Body()",
std::string("DeviceId #") + m_sDeviceId);
}
_tev__PullMessages PullMessages;
PullMessages.Timeout = "PT1M";
PullMessages.MessageLimit = 1024;
_tev__PullMessagesResponse PullMessagesResponse;
int nRetCode = SOAP_OK;
if ((nRetCode = PullPointProxy.PullMessages(&PullMessages, PullMessagesResponse)) == SOAP_OK)
{
for (auto msg : PullMessagesResponse.wsnt__NotificationMessage)
{
ProcessOnvifMessage(msg->Message.__any);
}
}
else
{
PullPointProxy.soap_stream_fault(std::cerr);
m_Logger.LogMessage(
NLogger2::ePriorityLevelError,
std::string("PullPointProxy.PullMessages() error code is ") + std::to_string(nRetCode),
"COnvifMotionDetectorWorker::Body()",
std::string("DeviceId #") + m_sDeviceId);
}
// Wait for nothing
std::this_thread::sleep_for(std::chrono::seconds(1));
}
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- Onvif PullpointProxy Pullmessages返回错误401未经授权
- 如何修复401:发出POST请求时出现未经授权的错误C++/Qt
- 从 twitcurl 时间线获取未授权错误用户获取方法
- HTTP/1.1 401使用GSOAP调用EWS时出现未经授权的错误
- 发送GetItem请求时出现未经授权的错误
- 是KDE Qt授权问题信息误导或Qt.io是错误的